使用按多列分组时可以得到完整的行吗?

Can I get the full rows when using group by multiple columns?

如果 table 中的日期、项目和类别相同, 我想将其视为同一行,其中 return n 行(例如:如果 n 为 3,则限制为 0、3)。

------------------------------------------
id   |  date   | item   | category   | ...
------------------------------------------
101  | 20220201| pencil | stationery | ...    <---
------------------------------------------        |  treat as same result
105  | 20220201| pencil | stationery | ...    <---  
------------------------------------------
120  | 20220214| desk   | furniture  | ...
------------------------------------------
125  | 20220219| tongs  | utensil    | ...    <---
------------------------------------------        |  treat as same
129  | 20220219| tongs  | utensil    | ...    <--- 
------------------------------------------
130  | 20220222| tongs  | utensil    | ...

预期结果(如果 n 为 3)

-----------------------------------------------
id   |  date   | item   | category   | ... rank
-----------------------------------------------
101  | 20220201| pencil | stationery | ...  1  
-----------------------------------------------       
105  | 20220201| pencil | stationery | ...  1  
-----------------------------------------------
120  | 20220214| desk   | furniture  | ...  2
-----------------------------------------------
125  | 20220219| tongs  | utensil    | ...  3
-----------------------------------------------
129  | 20220219| tongs  | utensil    | ...  3

问题是我还必须带上每个组的值。 如果我只有一列作为分组依据,我可以将 id 值与 origin table 进行比较,但我不知道如何处理多个列。

有什么办法可以解决这个问题吗?

作为参考,我使用用户变量将其与以前的值进行比较, 无法使用,因为持续时间很慢

          SELECT 
            *,
            IF(@prev_date=date and @prev_item=item and @prev_category=category,@ranking, @ranking:=@ranking+1) AS sameRow,
            @prev_item:=item,
            @prev_date:= date,
            @prev_category:=category,
            @ranking
          FROM ( SELECT ...

我使用的是Mysql 8.0版本,id值不是一个连续的数字,因为我必须先排序再分组。

如果我没理解错的话,你可以尝试使用 dense_rank window 函数并设置 order by 为你期望的列

如果date列可以代表订单号我会放在第一位。

SELECT *
FROM (
    SELECT *,dense_rank() OVER(ORDER BY date, item, category) rnk
    FROM T 
) t1

SQLFIDDLE

Window 函数在这种情况下非常有用。但对于我们这些仍在使用 MySQL 5.7 的人来说,row_number 等功能不存在,我们不得不求助于使用用户变量并每次在主语句之前重置该值,或者直接在语句中定义用户变量。
方法一

set @row_id=0; -- remember to reset the row_id to 0 every time before the main query below
select id,date,item,category,rank from testtb join 
    (
    select date,item,category, (@row_id:=@row_id+1) as rank
        from 
            (select date,item,category  from testtb group by date,item,category) t1
    ) t2 
using(date,item,category);

方法二

select id,date,item,category,rank from testtb join 
    (
    select date,item,category, (@row_id:=@row_id+1) as rank
        from 
            (select date,item,category  from testtb group by date,item,category) t1, (select @row_id := 0) as n
    ) t2 
using(date,item,category);