我有一张桌子:
ID | date | Location A | Location B
1234 2018-06-16 Chicago Chicago
1234 2018-06-15 Chicago Chicago
1234 2018-06-14 Chicago Chicago
1234 2018-06-13 Chicago Florida
1234 2018-06-12 Baltimore Florida
1234 2018-06-11 California Florida
1234 2018-06-10 California Florida
4444 2018-06-16 Utah Utah
4444 2018-06-15 Utah Utah
4444 2018-06-14 Utah Utah
4444 2018-06-13 Chicago Utah
4444 2018-06-12 Baltimore Utah
4444 2018-06-11 California Florida
4444 2018-06-10 California Florida
6214 2018-06-16 Baltimore Baltimore
6214 2018-06-15 Baltimore Baltimore
6214 2018-06-14 Baltimore Baltimore
6214 2018-06-13 Baltimore Florida
6214 2018-06-12 Baltimore Florida
6214 2018-06-11 Baltimore Florida
我的目标是要有一个新列来指示自位置A和位置B匹配以来的天数,但前提是之前它们不匹配并且位置B与当天或之前相同的位置相同将A更改为匹配项,并且“日期”为最新日期。
上表将如下所示
ID | date | Location A | Location B | Days Matched
1234 2018-06-16 Chicago Chicago 3
4444 2018-06-16 Utah Utah 3
ID 6214不会出现在表格中,因为位置A已经比位置B多1天了。
答案 0 :(得分:0)
我可以毫不费力地给出的最佳尝试:
这是查询
SELECT A.ID, A.DATE, A.LOCATIONA, A.LOCATIONB,
(SELECT COUNT(*) FROM TABLE V WHERE A.ID=V.ID AND (A.NOTMATCHEDDATE IS NULL OR V.NOTMATCHEDDATE>A.NOTMATCHEDDATE) AS CNT
FROM
(
SELECT ID, DATE, LOCATIONA, LOCATIONB,
(
SELECT MIN(DATE) FROM TABLE U WHERE T.ID=U.ID AND U.LOCATIONA<>U.LOCATIONB)
) AS NOTMATCHEDDATE,
FROM TABLE T
WHERE LOCATIONA=LOCATIONB AND
NOT EXISTS(SELECT * FROM TABLE S WHERE S.ID=T.ID AND S.DATE>T.DATE)
) A
答案 1 :(得分:0)
我自己并不遵守所有规则。特别是当芝加哥从未被“建议”时,我仍然不明白为什么要使用1234 / Chicago。这是一个刺:
with x as (
select *,
row_number() over (partition by ID order by DT desc) as rn,
first_value(LocationA) over (partition by ID order by DT desc) as fv,
count(*) over (partition by ID, LocationB) as cntB,
count(case when LocationA = LocationB then 1 end) over (partition by ID) as cntE
from T
), y as (
select * from x where cntB > cntE
)
select cntE from y
where rn = 1 and DT = cast(getdate() as date);
这有点通用,但是我的印象是您的位置和建议顺序受到了足够的限制,可能会起作用。另外,我继续使用first_value()
,意识到您可能无法使用它。
在此处找到一些DDL:http://rextester.com/CRST10642
编辑
这可能完全是错误的,但这是另一种想法:
with x as (
select *,
row_number() over (partition by ID order by DT desc) as rn,
first_value(LocationA) over (partition by ID order by DT desc) as fv,
count(*) over (partition by ID, LocationB) as cntB,
count(case when LocationA = LocationB then 1 end) over (partition by ID) as cntE
from T
), y as (
select *,
max(case when LocationA = fv then rn end) over (partition by ID) as maxA,
max(case when LocationB = fv then rn end) over (partition by ID) as maxB
from x
)
select * from y where rn = 1 and maxB + 1 >= maxA;