答案 0 :(得分:4)
您可以使用窗口函数和CTE将行号分配给“数据”的每个分区,然后在行号为1时将标志设置为1,否则为0。
这假定:
。
With CTE AS (SELECT Data, Row_Number() over (partition by Data order by Data) RN
FROM TableName T)
SELECT Data, case when RN = 1 then 1 else 0 end as Flg
FROM CTE
鉴于我使用的示例数据,返回类似的内容:
Data Flg
1 A 1
2 A 0
3 B 1
4 B 0
5 B 0
6 C 1
7 C 0
答案 1 :(得分:0)
首先,无法自动设置和更新表中的该值。在对表进行每次修改之后,都必须重新计算它们,并且计算出的列不能引用其他行,或者执行完整的查询。
您可以使用LAG
之类的窗口函数根据您提供的搜索顺序检查集合中是否存在先前的值,例如:
declare @t table (data varchar(10))
insert into @t
values ('A'),
('B'),
('A'),
('B'),
('B'),
('C'),
('C')
SELECT
Data,
iif( lag(1) over (partition by Data order by Data) is null,1,0) as Value
FROM @t
这将返回:
Data Value
A 1
A 0
B 1
B 0
B 0
C 1
C 0
lag(1) over (partition by Data order by Data)
按数据列中的值对行进行分区,并按相同的值对行进行排序,从而产生随机顺序。然后,它返回该分区的“上一个”值。对于第一行,没有任何内容,并且LAG
返回null
。
iif( ... is null,1,0) as Value
检查结果,如果为空,则返回1,否则返回0。
如果要将更改存储到表中,可以使用可更新的CTE:
declare @t table (data varchar(10),value bit)
insert into @t(data)
values ('A'),
('B'),
('A'),
('B'),
('B'),
('C'),
('C');
with x as ( SELECT
Data,value,
iif( lag(1) over (partition by Data order by Data) is null,1,0) as Val
FROM @t)
update x
set value=val
from @t;
select *
from @t
order by data
您可以在INSERT,UPDATE,DELETE上使用触发器,以在每次修改时运行该查询并更新表。最好进行所有修改并仅在最后执行UPDATE
答案 2 :(得分:0)
SQL表表示无序集。创建表后,您的表没有足够的信息来回答这个问题。
如果您有这样的表,则可以使用诸如此类的查询来分配值:
select value,
(case when row_number() over (partition by value order by ?) = 1
then 1 else 0
end) as flag
from t;
?
是createdAt
或id
之类的列的占位符,用于指定表中值的顺序。
如果没有指定顺序的列,则可以使用触发器检查此值是否已存在。但是,与其建议编写触发器,不建议创建带有identity()
列或createdAt
列(或两者)的表以捕获插入顺序。