这是输出。
ID Stack
-----------------------------------
123 307290,303665,307285
123 307290,307285,303424,303665
123 307290,307285,303800,303665
123 307061,307290
我想要输出只有最后三行。原因是在第一个输出线堆栈列中,所有三个数字在输出行2和3堆栈列中都可用,因此我不需要输出行1.
但是输出行2,3,4是不同的所以我想在结果中使用这些行。
我尝试使用row_number()
和charindex
,但我没有得到正确的结果。
谢谢。
答案 0 :(得分:0)
所有评论都告诉您更改数据库的结构是正确的!你真的应该避免使用逗号分隔值。这打破1.NF,永远是痛苦的。
第二个CTE的结果可能用于将所有数据转换为新的1:n
相关结构。
这样的东西?
DECLARE @tbl TABLE(ID INT,Stack VARCHAR(100));
INSERT INTO @tbl VALUES
(123,'307290,303665,307285')
,(123,'307290,307285,303424,303665')
,(123,'307290,307285,303800,303665')
,(123,'307061,307290');
WITH Splitted AS
(
SELECT ID
,Stack
,ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS RowIndex
,CAST('<x>' + REPLACE(Stack,',','</x><x>') + '</x>' AS XML) Casted
FROM @tbl
)
,DerivedDistinctValues AS
(
SELECT DISTINCT
ID
,Stack
,RowIndex
,StackNr.value('.','int') AS Nr
FROM Splitted
CROSS APPLY Casted.nodes('/x') AS A(StackNr)
)
SELECT ddv1.ID
,ddv1.Stack
FROM DerivedDistinctValues AS ddv1
FULL OUTER JOIN DerivedDistinctValues AS ddv2 ON ddv1.RowIndex<>ddv2.RowIndex
AND ddv1.Nr=ddv2.Nr
WHERE ddv2.ID IS NULL
GROUP BY ddv1.ID,ddv1.Stack
这将很慢,特别是对于较大的数据集。
一些解释:
第一个CTE会将CSV编号转换为<x>307290</x><x>303665</x>...
这可以转换为XML,这允许生成一个派生表,将所有数字作为行返回。这发生在调用XQuery函数.nodes()
的第二个CTE中。
最后一个查询将执行完全外部连接 - 每个连接都有一个。将保留所有行,其中至少有一行没有相应的行。
但我认为,这可能不适用于每种情况(例如循环数据)