Pea*_*nut 8 mysql sql group-by
我有一个包含start_date和end_date列的表.我们需要做的是选择所有内容并按每个Object_ID的日期冲突对它们进行分组.
日期冲突是指行的开始日期和/或结束日期通过另一行'.例如,以下是冲突的一些示例:
第1行的日期为1日至5日,第2行的日期为2日至3日.
第1行的日期是第2到第5,第2行的日期是第1到第3.
第1行的日期是第2到第5,第2行的日期是第3到第6.
第1行的日期是第2到第5,第2行的日期是第1到第7.
例如,如果我们有一些样本数据(假设数字只是一个月中的简单日期):
id | object_id | start_date | end_date
1 | 1 | 1 | 5
2 | 1 | 2 | 4
3 | 1 | 6 | 8
4 | 2 | 2 | 3
Run Code Online (Sandbox Code Playgroud)
我期望看到的是:
object_id | start_date | end_date | numconflicts
1 | <na> | <na> | 2
1 | 6 | 8 | 0 or null
2 | 2 | 3 | 0 or null
Run Code Online (Sandbox Code Playgroud)
对于第二个测试用例,以下是一些示例数据:
id | object_id | start_date | end_date
1 | 1 | 1 | 5
2 | 1 | 2 | 4
3 | 1 | 6 | 8
4 | 2 | 2 | 3
5 | 2 | 4 | 5
6 | 1 | 2 | 3
7 | 1 | 10 | 12
8 | 1 | 11 | 13
Run Code Online (Sandbox Code Playgroud)
对于第二个测试用例,我期望看到输出:
object_id | start_date | end_date | numconflicts
1 | <na> | <na> | 3
1 | 6 | 8 | 0 or null
2 | 2 | 3 | 0 or null
2 | 4 | 5 | 0 or null
1 | <na> | <na> | 2
Run Code Online (Sandbox Code Playgroud)
是的,我需要一些区分第一和第二组的方法(第一行和最后一行),但我还没有想到这一点.目标是查看此列表,然后当您单击一组冲突时,您可以查看该组中的所有冲突.
我的第一个想法是尝试一些GROUP BY CASE ......条款,但我只是围绕着自己.
我用来调用mysql的语言是php.因此,如果有人知道一个php循环解决方案而不是一个大型的mysql查询,那我就是耳朵.
提前致谢.
编辑:在主键中添加,以减少混淆.
编辑:在测试用例2中添加以提供更多推理.
此查询查找重复项的数量:
select od1.object_id, od1.start_date, od1.end_date, sum(od2.id is not null) as dups
from object_date od1
left join object_date od2
on od2.object_id = od1.object_id
and od2.end_date >= od1.start_date
and od2.start_date <= od1.end_date
and od2.id != od1.id
group by 1,2,3;
Run Code Online (Sandbox Code Playgroud)
您可以使用此查询作为查询的基础,该查询可以准确地提供您所要求的内容(请参阅下面的输出)。
select
object_id,
case dups when 0 then start_date else '<na>' end as start_date,
case dups when 0 then end_date else '<na>' end as end_date,
sum(dups) as dups
from (
select od1.object_id, od1.start_date, od1.end_date, sum(od2.id is not null) as dups
from object_date od1
left join object_date od2
on od2.object_id = od1.object_id
and od2.end_date >= od1.start_date
and od2.start_date <= od1.end_date
and od2.id != od1.id
group by 1,2,3) x
group by 1,2,3;
Run Code Online (Sandbox Code Playgroud)
请注意,我使用了id列来区分行。但是,您可以将 id 不匹配的测试替换为每列上的比较,即替换od2.id != od1.id为每个其他列不相等的测试,但这需要所有其他列上的唯一索引才有意义,并且具有 id 列无论如何是个好主意。
这是使用您的数据进行的测试:
create table object_date (
id int primary key auto_increment,
object_id int,
start_date int,
end_date int
);
insert into object_date (object_id, start_date, end_date)
values (1,1,5),(1,2,4),(1,6,8),(2,2,3);
Run Code Online (Sandbox Code Playgroud)
针对此示例数据运行时第一个查询的输出:
+-----------+------------+----------+------+
| object_id | start_date | end_date | dups |
+-----------+------------+----------+------+
| 1 | 1 | 5 | 1 |
| 1 | 2 | 4 | 1 |
| 1 | 6 | 8 | 0 |
| 2 | 2 | 3 | 0 |
+-----------+------------+----------+------+
Run Code Online (Sandbox Code Playgroud)
针对此示例数据运行时第二个查询的输出:
+-----------+------------+----------+------+
| object_id | start_date | end_date | dups |
+-----------+------------+----------+------+
| 1 | 6 | 8 | 0 |
| 1 | <na> | <na> | 2 |
| 2 | 2 | 3 | 0 |
+-----------+------------+----------+------+
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
292 次 |
| 最近记录: |