我有两个列表,我想看看两个列表没有共同点。例如:
List1:
'a','b','c','123'
List2:
'd','e','f','a','asd','c'
我希望输出为:
'b','123','d','e','f','asd'
这样的东西?
select * from ('a','b','c','123')
join ('d','e','f','a','asd','c')
on ???
是否有一个纯SQL Server解决方案,而不使用表?
答案 0 :(得分:5)
如果您可以控制列表,我只会将它们设为表变量:
DECLARE @a TABLE (str varchar(100))
INSERT INTO @a
VALUES
('a'),
('b')...
DECLARE @b table (str varchar(100))
INSERT INTO @b
VALUES
...
(SELECT str FROM @a
EXCEPT
SELECT str FROM @b)
UNION
(SELECT str FROM @b
EXCEPT
SELECT str FROM @a)
答案 1 :(得分:3)
鉴于此功能:
CREATE FUNCTION dbo.SplitStrings ( @List NVARCHAR(MAX) )
RETURNS TABLE
AS
RETURN ( SELECT Item FROM (
SELECT Item = x.i.value('(./text())[1]', 'nvarchar(max)')
FROM (
SELECT [XML] = CONVERT(XML, '<i>' + REPLACE(@List,',', '</i><i>')
+ '</i>').query('.')) AS a CROSS APPLY [XML].nodes('i') AS x(i)
) AS y WHERE Item IS NOT NULL);
GO
您可以使用完整的外部联接:
DECLARE
@list1 NVARCHAR(MAX) = N'a,b,c,123',
@list2 NVARCHAR(MAX) = N'd,e,f,a,asd,c',
@output NVARCHAR(MAX) = N'';
SELECT @output += N',' + COALESCE(l1.Item, l2.Item)
FROM dbo.SplitStrings(@list1) AS l1
FULL OUTER JOIN dbo.SplitStrings(@list2) AS l2
ON l1.Item = l2.Item
WHERE l1.Item IS NULL OR l2.Item IS NULL;
SELECT STUFF(@output, 1, 1, N'');
或类似于@ JNK:
DECLARE
@list1 NVARCHAR(MAX) = N'a,b,c,123',
@list2 NVARCHAR(MAX) = N'd,e,f,a,asd,c',
@output NVARCHAR(MAX) = N'';
;WITH l1 AS (SELECT Item FROM dbo.SplitStrings(@list1)),
l2 AS (SELECT Item FROM dbo.SplitStrings(@list2))
SELECT @output += N',' + Item
FROM ( (SELECT Item FROM l1 EXCEPT SELECT Item FROM l2)
UNION
(SELECT Item FROM l2 EXCEPT SELECT Item FROM l1)) AS x;
SELECT STUFF(@output, 1, 1, N'');
也许还有其他各种方式。如果订单很重要,它会变得更复杂,但仍然可能。
答案 2 :(得分:1)
没有简单的方法来实现这一目标。要过滤列表中的值,您需要将它们作为行。所以你最终会得到类似的东西:
SELECT col FROM (
SELECT 'a' as col
UNION
SELECT 'b'
UNION
SELECT 'c') t
WHERE col NOT IN ('a', 'b')
答案 3 :(得分:1)
怎么样:
with
list1(j) as (select 'a' union select 'b'),
list2(j) as (select 'b' union select 'c')
select coalesce(list1.j, list2.j)
from list1 full join list2
on list1.j = list2.j
where (list1.j is null or list2.j is null)
答案 4 :(得分:0)
我认为您必须将值插入2个变量表中。
DECLARE @Table1 TABLE (Value VARCHAR(1))
DECLARE @Table2 TABLE (Value VARCHAR(1))
INSERT INTO @Table1 (Value) VALUES ('a')
INSERT INTO @Table1 (Value) VALUES ('b')
INSERT INTO @Table2 (Value) VALUES ('b')
INSERT INTO @Table2 (Value) VALUES ('c')
然后对2个表执行一些设置操作。
DECLARE @TableUnion TABLE (Value VARCHAR(1))
DECLARE @TableIntersection TABLE (Value VARCHAR(1))
DECLARE @TableExcept TABLE (Value VARCHAR(1))
INSERT INTO @TableUnion
SELECT * FROM
((SELECT * FROM @Table1)
UNION
(SELECT * FROM @Table2)) U
INSERT INTO @TableIntersection
SELECT * FROM
((SELECT * FROM @Table1)
INTERSECT
(SELECT * FROM @Table2)) I
INSERT INTO @TableExcept
SELECT * FROM
((SELECT * FROM @TableUnion)
EXCEPT
(SELECT * FROM @TableIntersection)) E
最终select语句的结果集将包含'a'和'c'。哪个可以连接成一个字符串,如下所示。
DECLARE @ExceptString VARCHAR(3)
SELECT @ExceptString =
CASE
WHEN @ExceptString IS NULL THEN Value
ELSE @ExceptString + ',' + Value
END
FROM @TableExcept