1

I'm using the following query, to select the lowest price in the database, along with all the additional data needed.

SELECT 
    p1.id as pid, p1.persons, p1.skipas_incl, temp.* 
FROM
    winter_accommodaties_prijzen p1
INNER JOIN (
    SELECT
        a.id as accom_id, p.vertrekdatum, Min(p.prijs) as prijs, a. max_personen, a.naam as naam, g.pistes_groen+g.pistes_blauw+g.pistes_rood+g.pistes_zwart as pistes, liften_type1+liften_type2+liften_type3+liften_type4 as liften, g.naam as gebied, g.lid, d.gid, d.naam as dorp, d.hoogte_dorp, d.afstand_utrecht, d.dalafdaling, g.min_hoogte, g.max_hoogte, t.naam as typenaam, afstand_piste
    FROM
        winter_accommodaties_prijzen p
        INNER JOIN winter_accommodaties a ON (a.id = p.accid)
        INNER JOIN winter_dorpen d ON (d.id = a.did)
        INNER JOIN winter_gebied g ON (g.id = d.gid)
        INNER JOIN winter_accommodaties_types t ON (a.tid = t.id)
    WHERE
        g.lid IN(1,2) AND (p.vertrekdatum BETWEEN '2016-08-30' AND '2017-06-30' OR p.vertrekdatum = '0000-00-00') AND g.max_hoogte >= 500 AND (g.pistes_groen+g.pistes_blauw+g.pistes_rood+g.pistes_zwart) >= 50 AND d.hoogte_dorp >= 500 AND d.afstand_utrecht <= 2500 AND prijs < 1200 AND p.persons >= 4
    GROUP BY
        p.accid
    ORDER BY 
        prijs, naam ASC
    LIMIT
        0, 10) AS temp
ON 
    temp.accom_id = p1.accid AND 
    temp.prijs = p1.prijs AND
    temp.vertrekdatum = p1.vertrekdatum
GROUP BY
    p1.accid

The SELECT between brackets selects the various fields needed and the lowest price. The 'vertrekdatum' which is a date used in the parent query to get the correct price_id. This as a price/accommodation can have multiple leave dates, hence the combination between

price<->ID<->date

The problem currently is, is that the date selected (and possible other fields also), are not perse linked to the row with the MIN(p.prijs), resulting in an error in the parent query e.g. it only shows a selection on which it accidentally goes right.

I'm struggling on how to resolve this issue, as I have tried various options/linkages between tables, but don't get the expected outcome. Could you guys help me on a suggestion how to improve this query so it provides the expected outcome?

Solution

After some testing, playing around and lots of searching, the following is the outcome which works for me:

SELECT              
    subset.*, a.max_personen, a.naam as naam
FROM                
    (
    SELECT
        temp.*,
        @rowNum := if(@prevValue = temp.accom_id, @rowNum+1, 1) as row_num, 
        @prevValue := temp.accom_id as accid1
    FROM
        (
        SELECT
            p.id as pid, p.accid as accom_id, p.prijs, p.vertrekdatum,   p.persons, p.skipas_incl, g.pistes_groen+g.pistes_blauw+g.pistes_rood+g.pistes_zwart as pistes, g.liften_type1+g.liften_type2+g.liften_type3+g.liften_type4 as liften, g.naam as gebied, g.lid, d.gid, d.naam as dorp, d.hoogte_dorp, d.afstand_utrecht, d.dalafdaling, g.min_hoogte, g.max_hoogte, t.naam as typenaam, a.afstand_piste                    
        FROM                        
            winter_accommodaties_prijzen p                      
            INNER JOIN winter_accommodaties a ON (a.id = p.accid)                       
            INNER JOIN winter_dorpen d ON (d.id = a.did)                        
            INNER JOIN winter_gebied g ON (g.id = d.gid)                        
            INNER JOIN winter_accommodaties_types t ON (a.tid = t.id)                   
        WHERE                       
            g.lid IN(1,2) 
            AND (p.vertrekdatum BETWEEN '2016-09-16' AND '2017-05-16' OR   p.vertrekdatum = '0000-00-00') 
            AND g.max_hoogte >= 500 
            AND (g.pistes_groen+g.pistes_blauw+g.pistes_rood+g.pistes_zwart) >= 50
            AND d.hoogte_dorp >= 500 
            AND d.afstand_utrecht <= 2500
            AND prijs < 1200 
            AND p.persons >= 4                  
        ORDER BY                         
            p.accid, p.prijs ASC, p.vertrekdatum) temp,             
        (SELECT @rowNum := 1 FROM DUAL) X,              
        (SELECT @prevValue := -1 FROM DUAL) Y) subset           
INNER JOIN winter_accommodaties a ON (a.id = subset.accom_id)           
WHERE               
    subset.row_num = 1           
ORDER BY 
    prijs, naam ASC         
LIMIT               
    0, 10
Ralf
  • 253
  • 1
  • 11
  • This is a very common query, pls do some googling next time before asking a question. – Shadow Sep 14 '16 at 15:14
  • The difficulty I'm running into, is that I group by an ID, which is different then the primary/unique key in the price table. Even the option 'select id, min(price) from table group by second_id' gives not the right ID back to which the parent query can link to. The reason for the query, is that the min price has some condition it needs to match. Any suggestion if this is even possible? – Ralf Sep 14 '16 at 19:07
  • It doesn't matter by what field you group by. The theory is exactly the same as explained in the duplicate topic. – Shadow Sep 14 '16 at 19:11
  • @Shadow not sure if I can follow. I have the following query. The ID which is being outputted is the wrong ID e.g. different row. This is the minimal I can clean out the above query. the group by id is not unique. Any suggestions? SELECT p1.id, min(p1.prijs) as prijs FROM winter_accommodaties_prijzen p1 WHERE (p1.vertrekdatum BETWEEN '2016-08-30' AND '2017-06-30' OR p1.vertrekdatum = '0000-00-00') AND p1.accid = 80 AND p1.prijs < 1200 AND p1.persons = 4 GROUP BY p1.accid – Ralf Sep 14 '16 at 19:34
  • I'm sorry, but all this is explained in a very detailed manner in the accepted answer of the duplicate topic. The only difference is that they use max, and you want min. – Shadow Sep 15 '16 at 00:45
  • I manage to find a solution, not in the duplicate topic, as it assumes that the ID on which it's grouped by, is unique and can be used for future linkage, which is not possible in my dataschema. In the end I have added rownum's via Mysql and use those for the unique reference. – Ralf Sep 15 '16 at 10:59
  • None of the solutions in the duplicate topic assume that the field on which the query group by is unique. You can relate a subquery back on the main table on any common fields. – Shadow Sep 15 '16 at 11:16

0 Answers0