简体   繁体   中英

MYSQL Using Limit In Group By

I have this kind of query that need to limit by 3 in each 'region' group but it doesnt run as I expected. The 'row_number' seems not arranged accordingly. There must be some syntax I missed out or I didnt know. If anyone can help I dump the sql Here . MYSQL version 5.0

My query :

set @type = '';
set @num = 0;

SELECT locinvaisle.Area as ar,locinvaisle.Region as rg,custlist.CustomerName as cn,custlist.Custtype ct,
       SUM(data2.quantity/1000) as mtcur,
       @num := if(@type = locinvaisle.Region, @num + 1, 1) as dummy_1,
  @type := locinvaisle.Region as dummy_2,
  @num as row_number

FROM data2

  INNER JOIN custlist ON data2.customeracc = custlist.Customeraccount
  INNER JOIN locinvaisle ON data2.location = locinvaisle.Location

WHERE
   date1 >= DATE_FORMAT('2018-06-11', '%Y-01-01') AND date1 <= DATE_FORMAT('2018-06-11', '%Y-%m-31')
  AND
   data2.unit = 'KG'
  AND
   data2.customeracc not in (select Customeraccount from custlist WHERE Custcat = 'bcsb')
  AND
   locinvaisle.Area = 'peninsular'
  AND
   custlist.Custtype = 'others'

GROUP BY locinvaisle.Region,custlist.CustomerName
HAVING row_number < 3
ORDER BY locinvaisle.Region,mtcur desc

Results :

结果

Desired Results(From dummy database) :

假

You have to do the limiting as a full subquery ("derived table") before the group by is applied. Something along these lines:

SELECT 
       ar, rg, cn, ct, sum(quantity)
FROM (
    SELECT
          @row_num :=IF(@prev_value = locinvaisle.Region, @row_num + 1, 1)AS RowNumber
        , locinvaisle.Area as ar
        , locinvaisle.Region as rg
        , custlist.CustomerName as cn
        , custlist.Custtype ct
        , data2.quantity
        , @prev_value := locinvaisle.Region as dummy_2,
    FROM data2
      INNER JOIN custlist ON data2.customeracc = custlist.Customeraccount
      INNER JOIN locinvaisle ON data2.location = locinvaisle.Location
      CROSS JOIN (SELECT @row_num :=1,  @prev_value :='') vars
    WHERE date1 >= DATE_FORMAT('2018-06-11', '%Y-01-01') AND date1 <= DATE_FORMAT('2018-06-11', '%Y-%m-31')
      AND data2.unit = 'KG'
      AND data2.customeracc not in (select Customeraccount from custlist WHERE Custcat = 'bcsb')
      AND  locinvaisle.Area = 'peninsular'
      AND custlist.Custtype = 'others'
    ORDER BY locinvaisle.Region,mtcur desc
    ) d
WHERE rowNumber <= 3
GROUP BY ar, rg, cn, ct
ORDER BY ar, rg, cn, ct

NOTE: You need to apply an ORDER BY within the subquery to facilitate the rownumber calculation, but despite this there is no guarantee that the final output will be in the desired order unless you apply a final order by clause.

Also please note that in future versions of MySQL (V8 and above) there should be a row_number() function and over() clause that can be used instead of the variables seen above.

In MySQL, you need to be careful when using variables. Two things are important:

  • Variables should be assigned and referenced in the same expression.
  • You need to be careful about the ordering of the result set.

So, try something like this:

SELECT x.*,
       (@rn := IF(@r = la.Region, @num + 1,
                  IF(@r := la.Region, 1, 1)
                 )
       ) as rn
FROM (SELECT la.Area as ar, la.Region as rg, c.CustomerName as cn, c.Custtype ct,
             SUM(data2.quantity/1000) as mtcur
      FROM data2 d INNER JOIN
           custlist c
           ON d.customeracc = c.Customeraccount  INNER JOIN
           locinvaisle la
           ON d.location = la.Location
      WHERE date1 >= DATE_FORMAT('2018-06-11', '%Y-01-01') AND
            date1 <= DATE_FORMAT('2018-06-11', '%Y-%m-31') AND
            d.unit = 'KG' AND
            d.customeracc not in (select Customeraccount from custlist cl WHERE cl Custcat = 'bcsb') AND
            la.Area = 'peninsular' AND
            c.Custtype = 'others'
      GROUP BY la.Region, c.CustomerName
     ) x CROSS JOIN
     (SELECT @r := 0, @rn := 0) params
HAVING rn <= 3;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM