简体   繁体   English

MYSQL在分组依据中使用限制

[英]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. 我有这种查询,需要在每个“区域”组中限制3个,但它没有按我的预期运行。 The 'row_number' seems not arranged accordingly. “ row_number”似乎没有相应安排。 There must be some syntax I missed out or I didnt know. 一定有一些语法我错过了,或者我不知道。 If anyone can help I dump the sql Here . 如果有人可以帮助我在这里转储sql。 MYSQL version 5.0 MYSQL 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. 在应用group by之前,您必须将限制作为完整的子查询(“派生表”)进行。 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. 注意:您需要在子查询中应用ORDER BY来方便行号的计算,但是尽管如此,除非您应用final order by子句,否则不能保证最终输出将按期望的顺序进行。

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. 另外请注意,在将来的MySQL版本(V8及更高版本)中,应该使用row_number()函数和over()子句来代替上面看到的变量。

In MySQL, you need to be careful when using variables. 在MySQL中,使用变量时需要小心。 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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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