我有一张看起来像这样的表:
Field1 Field2 ValidFrom
200 a 01.01.1999
200 b 01.01.2015
210 c 01.01.2015
210 c 01.01.2010
现在我尝试生成一个带有附加列的select语句,当Field1保持不变但Field2发生变化时,该列会递增。 extraColumn中值的顺序应取决于ValidFrom,这意味着例如1为01.01.1999,2为2015年1月1日(而不是相反!)。 当Field1更改时,extraColumn中的值应该再次从1开始。当Field1和Field2的组合没有变化时,它应该保持相同的值。 所以我希望得到的结果如下:
extraColumn Field1 Field2 ValidFrom
1 200 a 01.01.1999
2 200 b 01.01.2015
1 210 c 01.01.2015
1 210 c 01.01.2010
我试图通过将此查询与RANK()函数一起使用来获得此结果:
select RANK() OVER (
PARTITION BY [Field1], [Field2]
ORDER BY [ValidFrom] DESC
) as 'extraColumn'
,Field1 ,Field2 ,ValidFrom
FROM table1
不幸的是,这并没有像我预期的那样起作用,它确实与我想要的相反,所以我的结果看起来像:
extraColumn Field1 Field2 ValidFrom
1 200 a 01.01.1999
1 200 b 01.01.2015
1 210 c 01.01.2015
2 210 c 01.01.2010
任何想法我做错了什么?
答案 0 :(得分:2)
使用DENSE_RANK
,您需要在Field2
中使用order by
才能获得所需的结果ValidFrom
DENSE_RANK() OVER (PARTITION BY [Field1] ORDER BY [Field2])
答案 1 :(得分:2)
Here我已经回答了类似的问题。以下是适应您的条件:
-- Preparation
declare @t table (
Field1 int,
Field2 char,
ValidFrom date
);
insert into @t (Field1, Field2, ValidFrom)
values
(200, 'a', '19990101'),
(200, 'b', '20150101'),
(210, 'c', '20150101'),
(210, 'c', '20100101');
-- The query
with cte as (
select t.*,
lag(t.Field2) over(partition by t.Field1 order by t.ValidFrom) as [Prev2]
from @t t
)
select c.Field1, c.Field2, c.ValidFrom,
sum(case when c.Prev2 = c.Field2 then 0 else 1 end)
over(partition by c.Field1 order by c.ValidFrom) as [ExtraColumn]
from cte c;
我只希望你不会对数百万或记录进行此操作,因为2分区不会让CPU和内存变得容易。哦,是的,您需要SQL Server 2012或更高版本才能实现此功能。
答案 2 :(得分:1)
尝试这样......
WITH
cte_MaxDate AS (
SELECT
*,
MaxDate = MAX(td.ValidFrom) OVER (PARTITION BY td.Feild1, td.Field2)
FROM
#TestData td
)
SELECT
DENSE_RANK() OVER (PARTITION BY md.Feild1 ORDER BY md.MaxDate, md.Field2),
md.Feild1, md.Field2, md.ValidFrom--, md.MaxDate
FROM
cte_MaxDate md;
答案 3 :(得分:1)
我认为你必须在这里使用递归来逐行计算,无论field2是否改变。
WITH CTE_RN AS
(
SELECT *
, ROW_NUMBER() OVER (PARTITION BY Field1 ORDER BY ValidFrom) RN
FROM Table1
)
, RCTE AS
(
SELECT *, 1 AS ExtraColumn
FROM CTE_RN WHERE RN = 1
UNION ALL
SELECT c.*
, CASE WHEN r.Field2 = c.Field2 THEN r.ExtraColumn ELSE r.ExtraColumn + 1 END
FROM RCTE r
INNER JOIN CTE_RN c ON r.Field1 = c.Field1 AND r.RN + 1 = c.RN
)
SELECT *
FROM RCTE
ORDER BY Field1, ValidFrom
OPTION (MAXRECURSION 0)
SQLFiddle DEMO (我为更复杂的样本添加了更多行)