MySQL:在 SELECT 查询期间为每个唯一出现的事件标记 1
Posted
技术标签:
【中文标题】MySQL:在 SELECT 查询期间为每个唯一出现的事件标记 1【英文标题】:MySQL: Tagging 1 to each unique occurence during SELECT query 【发布时间】:2020-04-11 22:03:32 【问题描述】:示例表 tbl_name:
| ID | Name | Month | Quarter | Year |
| 1 | A | Jan | 1 | 2019 |
| 1 | A | Feb | 1 | 2019 |
| 2 | B | May | 2 | 2019 |
| 3 | C | May | 2 | 2018 |
您好,这是我使用 SELECT 查询提取的表。我可以使用 SELECT distinct name, year FROM tbl_name;
找到每年的不同名称,但我试图在 SELECT 查询期间添加一列来识别或计算名称每年的唯一出现次数。
预期:
| ID | Name | Month | Quarter | Year | Unique Count |
| 1 | A | Jan | 1 | 2019 | 1 |
| 1 | A | Feb | 1 | 2019 | 0 |
| 2 | B | May | 2 | 2019 | 1 |
| 3 | C | May | 2 | 2018 | 1 |
我尝试分成两个查询 - 一个选择所有内容;另一个选择只是不同并将它们连接在一起,但这会引入重复。有没有办法使用 SQL 来做到这一点?
【问题讨论】:
为什么 2 月的计数比 1 月小? 为什么将月份存储为字符串而不包括正确指定排序的列? @GordonLinoff 这是源数据,我对此无能为力。我只能在我的一端使用它。 【参考方案1】:如果您运行的是 mysql 8.0,您可以使用row_number()
来标记name
在year
中的出现:
select
t.*,
(row_number() over(
partition by name, year
order by str_to_date(concat(year, '-', month), '%Y-%b')
) = 1) unique_count
from mytable t
注意:请考虑修复日期列的存储策略。与其将信息拆分为多个列,不如在相关的DATE
数据类型中拥有一个唯一列来存储该信息。这样可以省去您在需要时重新组合日期的痛苦。
Demo on DB Fiddle:
身份证 |姓名 |月 |季度 |年份 |唯一计数 -: | :--- | :---- | ------: | ---: | ------------: 1 |一个 |二月 | 1 | 2019 | 1 1 |一个 |一月 | 1 | 2019 | 0 2 |乙|五月 | 2 | 2019 | 1 3 | C |五月 | 2 | 2018 | 1【讨论】:
感谢您的 +1,我删除了我的 cmets。如果日期存储在单列中,对于 OP 来说,生活会轻松很多 :-) 太糟糕了,我无法控制表架构。有没有办法在不分区的情况下做到这一点?好像我用的软件不支持分区查询【参考方案2】:你可以试试下面这个逻辑-
DEMO HERE
WITH your_table(ID,Name,Month,Quarter,Year)
AS
(
SELECT 1,'A','Jan',1,2019 UNION ALL
SELECT 1,'A','Feb',1,2019 UNION ALL
SELECT 2,'B','May',2,2019 UNION ALL
SELECT 3,'C','May',2,2018
)
,CTE AS
(
SELECT *,ROW_NUMBER() OVER(PARTITION BY ID ORDER BY Quarter,Year) RN
FROM your_table
)
SELECT ID,Name,Month,Quarter,Year,
CASE WHEN RN = 1 THEN 1 ELSE 0 END Unique_Count
FROM CTE
输出是-
ID Name Month Quarter Year Unique_Count
1 A Jan 1 2019 1
1 A Feb 1 2019 0
2 B May 2 2019 1
3 C May 2 2018 1
【讨论】:
以上是关于MySQL:在 SELECT 查询期间为每个唯一出现的事件标记 1的主要内容,如果未能解决你的问题,请参考以下文章
mysql 如何按月分组查询出当前年度每个月的短信数量(数据库中这个月要是为空的话就用0条怎么显示出来)