Andy  Gee
Andy Gee

Reputation: 3335

Struggling adding WHERE clause to INNER JOIN

I have a query which is supposed to select the lowest price_per_pax_after_tax from every backend_hotels_id date_start and package_supplier and this appears to be working until I add a WHERE clause.

Here's the query:

SELECT e.price_per_pax_after_tax, e.hotel_score, e.package_id, e.package_type
FROM packages_sorted_YQU e
INNER JOIN (
  SELECT db_id, MIN( price_per_pax_after_tax ) AS lowest_price, package_id, hotel_score
  FROM `packages_sorted_YQU`
  WHERE `package_type` IN ('9', '10', '18') 
  AND `package_duration` IN ('6', '8', '12')
  GROUP BY 
    `date_start` , `package_supplier` , `backend_hotels_id`
) AS j 
ON j.db_id = e.db_id
AND j.lowest_price= e.price_per_pax_after_tax
AND j.hotel_score = e.hotel_score
AND j.package_id = e.package_id;

The table is huge but all of the fields listed are INT except for date_start which is DATE

The where clause causing the problem is:

WHERE `package_type` IN ('9', '10', '18') 
AND `package_duration` IN ('6', '8', '12')

Without the where clause I get over 400 results and with the where clause I get zero results :( Any help will be very much appreciated.

Upvotes: 0

Views: 969

Answers (3)

Andy  Gee
Andy Gee

Reputation: 3335

Hi all and thank you for your valuable input. I've solved the problem without a sub-query and it works a bit faster too.

SELECT MIN
(
    concat
    (
        LPAD(`price_per_pax_after_tax` , 5, '0'),
        LPAD(`package_id` , 12, '0'),
        LPAD(`hotel_score` , 7, '0')
    )
) AS cat
FROM `packages_sorted_YQU`
WHERE `package_type` IN
(
    9, 10, 18
)
AND `package_duration` IN
(
    6, 7, 8
)
GROUP BY `date_start` , `package_supplier` , `backend_hotels_id`

Then in PHP I break apart the concatenation with:

while($r=mysql_fetch_array($q,MYSQL_ASSOC))
{
    $a[lrp][] = intval(substr($r[cat], 0, 5));
    $a[package_id][] = intval(substr($r[cat], 5, 12));
    $a[hotel_score][] = substr($r[cat], 17, 7);
}

I was lucky that the only FLOAT value was the hotel_score so I put that last - the other two were of type INT

Upvotes: 0

ypercubeᵀᴹ
ypercubeᵀᴹ

Reputation: 115530

The subquery:

  SELECT db_id
       , MIN( price_per_pax_after_tax ) AS lowest_price
       , package_id
       , hotel_score
  FROM `packages_sorted_YQU`
  WHERE `package_type` IN ('9', '10', '18') 
  AND `package_duration` IN ('6', '8', '12')
  GROUP BY 
       `date_start` 
     , `package_supplier` 
     , `backend_hotels_id`

will yield indeterminate results, with or without the WHERE clause. Because you are grouping by date_start, package_supplier, backend_hotels_id and have in the SELECT list columns without any aggregate functions on them: db_id, package_id, hotel_score.

This query should work consistently if the (date_start, package_supplier, backend_hotels_id) is the Primary Key or Unique.

Which is the PRIMARY KEY of the table and are there any other UNIQUE keys?

Upvotes: 0

dgw
dgw

Reputation: 13646

If your columns package_type and package_duration are of type int you don't have to wrap the values inside ' like strings.

SELECT e.price_per_pax_after_tax, e.hotel_score, e.package_id, e.package_type
FROM packages_sorted_YQU e
INNER JOIN (
  SELECT db_id, MIN( price_per_pax_after_tax ) AS lowest_price, package_id, hotel_score
  FROM `packages_sorted_YQU`
  WHERE `package_type` IN (9, 10, 18) 
  AND `package_duration` IN (6, 8, 12)
  GROUP BY 
    `date_start` , `package_supplier` , `backend_hotels_id`
) AS j 
ON j.db_id = e.db_id
AND j.lowest_price= e.price_per_pax_after_tax
AND j.hotel_score = e.hotel_score
AND j.package_id = e.package_id;

Upvotes: 1

Related Questions