MYSQL在分组依据中使用限制

时间:2018-09-20 07:43:47

标签: mysql sql

我有这种查询,每个“区域”组中的查询都需要限制为3,但是它没有按我的预期运行。 “ row_number”似乎没有相应安排。 一定有一些语法我错过了,或者我不知道。如果有人可以帮忙,我将转储sql Here。 MYSQL 5.0版

我的查询:

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

所需结果(来自虚拟数据库):

dummy

2 个答案:

答案 0 :(得分:0)

在应用group by之前,您必须作为完整的子查询(“派生表”)进行限制。遵循以下原则:

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

注意:您需要在子查询中应用ORDER BY来方便行号的计算,但是尽管如此,除非您应用final order by子句,否则不能保证最终输出将按期望的顺序进行。

还请注意,在将来的MySQL版本(V8及更高版本)中,应该使用row_number()函数和over()子句代替上面列出的变量。

答案 1 :(得分:0)

在MySQL中,使用变量时需要小心。有两点很重要:

  • 应在同一表达式中分配和引用变量。
  • 您需要注意结果集的顺序。

所以,尝试这样的事情:

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;