为每个人选择每个月的前两项

Posted

技术标签:

【中文标题】为每个人选择每个月的前两项【英文标题】:Select the first two items in each month for each person 【发布时间】:2021-04-07 16:09:01 【问题描述】:

我想为每个人获取每个月的前两项。这个想法是如果项目具有相同的日期,它应该返回最大的金额。我无法为其编写一个简单的逻辑条件。

这是表格的截图: table datasource

代码应该是这样的

SELECT MONTH(date) as month, name,  item (WHERE Top 3 MONTH(date))
FROM table
GROUP BY MONTH(date), name,  item

预期的输出应该类似于以下内容: expected output

(编辑):对不起,这不适用于 SQL 服务器,我用标签误导了这个问题。我正在使用 phpmyadmin 进行 SQL 查询。很抱歉造成误会。

【问题讨论】:

【参考方案1】:

使用ROW_NUMBER:

WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY name, MONTH(date)
                                 ORDER BY date, quantity DESC) rn
    FROM yourTable
)

SELECT date, name, item, quantity
FROM cte
WHERE rn <= 2;

【讨论】:

它表示无法识别的语句类型“With”。我正在使用 phpmyadmin。所以现在我看到了使用 OVER(PARTITION BY...) 的模式。我对它不是很熟悉。你介意用简单的方式给我解释一下吗?【参考方案2】:

在处理日期时,您应该始终将年份考虑在内,除非您明确希望将多年的数据合并到一行中。您的问题中没有任何内容表明最终目标是合并来自不同时间段的数据。所以我建议:

SELECT YEAR(date) as year, MONTH(date) as month, name, item 
FROM (SELECT t.*,
             ROW_NUMBER() OVER (PARTITION BY YEAR(date), MONTH(date) ORDER BY date, quantity DESC) as seqnum
      FROM table t
     ) t
WHERE seqnum <= 2
ORDER BY MIN(date), name, item;

您还可以将数据明确限制为一年。

【讨论】:

这真的很高兴知道谢谢!现在我想我在将 mysql 服务器版本更新到最新版本时遇到问题。我不知道为什么它总是从每个人的代码中得到语法错误。 @chandler_liu 。 . .我对你的评论有点迷茫。该问题被标记为“sql-server”。所有受支持的 SQL Server 版本都将运行此代码。 我想我弄错了...不是针对 SQL server...我以为我正在处理的是 SQL server... 我正在使用 phpmyadmin。它说“服务器版本:5.7.30 - MySQL 社区服务器(GPL)”。所以我只是假设......现在我明白了。 SQL Server 是微软特定的东西......【参考方案3】:

更快的写法:

select top 2 with ties *
from [table]
order by row_number() over (partition by MONTH(date) as month, name order by date, quantity desc)

【讨论】:

【参考方案4】:

您可以使用如下解析函数:

select * from
(SELECT MONTH(date) as month, name, item, 
        row_number() 
          over (partition by MONTH(date), name order by date, quantity desc) 
        as rn
   FROM table) t
where rn <= 2

【讨论】:

接近尾声的 t 是什么意思? 第 4 行似乎有错误。“#1064 - 您的 SQL 语法有错误;请查看与您的 MySQL 服务器版本相对应的手册,以了解在 '(按 MONTH(sales_date) 划分为 sales_month,customer_id order by sales_date,'在第 4 行" 错误是由于分区中的关键字。我已经删除了它,t 只不过是给子查询的别名。

以上是关于为每个人选择每个月的前两项的主要内容,如果未能解决你的问题,请参考以下文章

获得池中每个人每月的前 3 名

您如何检索每个分组中的前两条记录

利用数组计算斐波那契数列

C语言经典习题

为每个 ID 选择每个月的最后一条记录

2017-11-06