我有一张这样的桌子......
id areaId date fromHour tohour
1 485 31-08-2015 10 16
2 485 31-08-2015 17 22
3 485 31-08-2015 13 16
4 460 31-08-2015 15 19
我使用了这个查询:
select t.* from tableName t
join (select areaId, date, count(*) as NumDuplicates
from tableName group by areaId, date having NumDuplicates > 1 ) tsum
on t.areaId = tsum.areaId and t.date = tsum.date
...我现在收到这样的结果集......
id areaId date fromHour tohour
1 485 31-08-2015 10 16
2 485 31-08-2015 17 22
3 485 31-08-2015 13 16
但是,我希望收到像这样的结果集......
id areaId date fromHour tohour
1 485 31-08-2015 10 16
3 485 31-08-2015 13 16
我现在要解释选择第1行和第3行的标准,但第2行和第4行不是......
选择第1行和第3行是因为:
它们具有相同的areaId和相同的Date,然后来自第3行的fromHour与第1行中的小时重叠。
从第3行开始,从第10行至第10行至第16行之间
未选择第2行和第4行,因为:
第2行与17到22之间的任何其他行没有重叠小时,其他行(第1行和第3行)在此时间之前。
第4行不在同一区域中,即使它具有相同的日期。
这是一个图表:
id areaId 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
1 485 |-----------------|
2 485 |--------------|
3 485 |--------|
4 460 |-----------|
结论:
我想选择具有相同areaId和date的行,只要它们有重叠的小时数(fromHour:toHour)。
答案 0 :(得分:0)
考虑以下内容......
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,area_id INT NOT NULL NULL
,date DATE NOT NULL
,from_hour INT NOT NULL
,to_hour INT NOT NULL
);
INSERT INTO my_table VALUES
(1 ,485 ,'2015-08-31' ,10 , 16),
(2 ,485 ,'2015-08-31' ,17 , 22),
(3 ,485 ,'2015-08-31' ,13 , 16),
(4 ,460 ,'2015-08-31' ,15 , 19);
SELECT DISTINCT x.*
FROM my_table x
JOIN my_table y
ON y.area_id = x.area_id
AND y.date = x.date
AND y.from_hour < x.to_hour
AND y.to_hour > x.from_hour
AND y.id <> x.id;
+----+---------+------------+-----------+---------+
| id | area_id | date | from_hour | to_hour |
+----+---------+------------+-----------+---------+
| 3 | 485 | 2015-08-31 | 13 | 16 |
| 1 | 485 | 2015-08-31 | 10 | 16 |
+----+---------+------------+-----------+---------+
请注意,您应该使用日期数据类型存储日期,并认真考虑存储datetime_start, datetime_end
而不是date, from_hour, to_hour
。
答案 1 :(得分:0)
我不满意这种方法尽可能高效,但它至少可以帮助讨论。我采用的具体方法需要一个整数表(我只使用0到24),用于确定这个子查询中各行的“共同”小时:
select
areaId, `date`, n.n
from tablename t
inner join tblNums n on n.n between t.fromHour and t.tohour
group by
areaId, `date`, n.n
having count(*) > 1
;
该子查询的结果(来自问题中的示例)是:
| areaId | date | n |
|--------|--------------------------|----|
| 485 | August, 31 2015 00:00:00 | 13 |
| 485 | August, 31 2015 00:00:00 | 14 |
| 485 | August, 31 2015 00:00:00 | 15 |
| 485 | August, 31 2015 00:00:00 | 16 |
该结果可以连接回源行(并且通过不同以避免重复)将列出共享重叠周期的行
select distinct
t.*
from tableName t
inner join (
select
areaId, `date`, n.n
from tablename t
inner join tblNums n on n.n between t.fromHour and t.tohour
group by
areaId, `date`, n.n
having count(*) > 1
) o on t.areaId = o.areaId and t.date = o.date
and t.fromHour = o.n or t.tohour = o.n
;
| id | areaId | date | fromHour | tohour |
|----|--------|--------------------------|----------|--------|
| 3 | 485 | August, 31 2015 00:00:00 | 13 | 16 |
| 1 | 485 | August, 31 2015 00:00:00 | 10 | 16 |
数据:
CREATE TABLE tableName
(`id` int, `areaId` int, `date` datetime, `fromHour` int, `tohour` int)
;
INSERT INTO tableName
(`id`, `areaId`, `date`, `fromHour`, `tohour`)
VALUES
(1, 485, '2015-08-31 00:00:00', 10, 16),
(2, 485, '2015-08-31 00:00:00', 17, 22),
(3, 485, '2015-08-31 00:00:00', 13, 16),
(4, 460, '2015-08-31 00:00:00', 15, 19)
;
CREATE TABLE tblNums
(`n` int)
;
INSERT INTO tblNums
(`n`)
VALUES
(0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),
(12),(13),(14),(15),(16),(17),(18),(19),(20),(21),(22),(23), (24);
答案 2 :(得分:0)
我过去得到我想要的最终查询,感谢@Strawberry
SELECT x.*
FROM my_table x
JOIN my_table y
ON y.area_id = x.area_id
AND y.date = x.date
AND y.from_hour <= x.to_hour
AND y.to_hour >= x.from_hour
AND y.id <> x.id;
我刚刚添加等于大于和小于,o避免在to_hour和from_hour等于时重叠小时。
再次感谢你。希望这有助于其他人。