突出显示日期范围内的多个记录

时间:2016-08-02 05:34:27

标签: sql sql-server database

使用SQL Server 2008

fromdate    todate     ID   name
--------------------------------
1-Aug-16    7-Aug-16    x   jack
3-Aug-16    4-Aug-16    x   jack
5-Aug-16    6-Aug-16    x   tom
1-Aug-16    2-Aug-16    x   john
3-Aug-16    4-Aug-16    x   harry
5-Aug-16    6-Aug-16    x   mac

有没有办法对此进行编写,以便我知道ID中是否有多个名称标记为same date range

例如,我要标记ID x在同一日期范围内标记了JackTom

ID  multiple_flag
------------------------------------------------
x   yes
y   no

3 个答案:

答案 0 :(得分:0)

如果您的表中有唯一索引(在我的示例中,它是列i,但您也可以通过使用ROW_NUMBER()生成一个索引),那么您可以基于以下内容执行以下查询INNER JOIN找到重叠的日期范围:

CREATE TABLE #tmp (i int identity primary key,fromdate date,todate date,ID int,name varchar(32));
insert into #tmp (fromdate,todate,ID ,name) values
('1-Aug-16','7-Aug-16',3,'jack'),
('3-Aug-16','4-Aug-16',3,'tom'),
('5-Aug-16','6-Aug-16',3,'jack');

select a.*,b.name bname,b.i i2 from #tmp a 
INNER join #tmp b on b.id=a.id AND b.i<>a.i
                    AND (   b.fromdate between a.fromdate and a.todate 
                         OR b.todate between a.fromdate and a.todate)

(我的id列为int)。这会给你:

i fromdate   todate    ID name bname i2 
- ---------- ---------- - ---- ----- -- 
1 2016-08-01 2016-08-07 3 jack tom   2  
1 2016-08-01 2016-08-07 3 jack jack  3  

根据需要实施进一步过滤或分组。我留下了一个小小的演示here

答案 1 :(得分:0)

请检查下面的sql,但它可能不是最佳的..

SELECT formdate,todate,id,tab1.name,
case when tab2.#Of >1 then 'yes' else 'no' end as multiple_flag
FROM tab1
inner join (SELECT Name, COUNT(*) as #Of
FROM tab1
GROUP BY Name) as tab2 on tab1.name=tab2.name
order by tab1.id ;
如果您需要在sql上添加一些日期范围,请在where之前添加order by条件。 在运行此sql之前将formdate更改为fromdate,因为我在我的计算机中使用了formdate

结果如

enter image description here

答案 2 :(得分:0)

一种方法是使用EXISTS CASE

请注意这部分查询:

-- make sure the records date ranges overlap
AND t1.fromdate <= t2.todate 
AND t2.fromdate <= t1.todate

有关测试重叠范围的说明,请阅读 wiki。

创建并填充示例数据(在将来的问题中将此步骤保存为我们)

DECLARE @T as table
(
    fromdate date,
    todate date,
    ID char(1),
    name varchar(10)
)

INSERT INTO @T VALUES
('2016-08-01', '2016-08-07', 'x', 'jack'),
('2016-08-03', '2016-08-04', 'x', 'tom'),
('2016-08-05', '2016-08-06', 'x', 'jack'),
('2016-08-01', '2016-08-02', 'y', 'john'),
('2016-08-03', '2016-08-04', 'y', 'harry'),
('2016-08-05', '2016-08-06', 'y', 'mac')

查询:

SELECT  DISTINCT id, 
    CASE WHEN  EXISTS
        (
            SELECT 1
            FROM @T t2
            WHERE t1.Id = t2.Id
            -- make sure it's not the same record
            AND t1.fromdate <> t2.fromdate 
            AND t1.todate <> t2.todate 
            -- make sure the records date ranges overlap
            AND t1.fromdate <= t2.todate 
            AND t2.fromdate <= t1.todate
        )
    THEN 'Yes' 
    ELSE 'No'
    END  As multiple_flag
FROM @T t1

结果:

id   multiple_flag
---- -------------
x    Yes
y    No
相关问题