Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/sharepoint/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在不使用表的情况下在SQL Server中执行联接_Sql_Sql Server_Sql Server 2008 - Fatal编程技术网

如何在不使用表的情况下在SQL Server中执行联接

如何在不使用表的情况下在SQL Server中执行联接,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我有两个列表,我想看看这两个列表没有什么共同点。例如: 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解决方案?实现这一点没有简单的方法。要从列表中筛

我有两个列表,我想看看这两个列表没有什么共同点。例如:

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解决方案?

实现这一点没有简单的方法。要从列表中筛选值,需要将它们作为行。所以你会得到这样的结果:

SELECT col FROM (
SELECT 'a' as col
UNION
SELECT 'b'
UNION
SELECT 'c') t

WHERE col NOT IN ('a', 'b')

要做到这一点并不容易。要从列表中筛选值,需要将它们作为行。所以你会得到这样的结果:

SELECT col FROM (
SELECT 'a' as col
UNION
SELECT 'b'
UNION
SELECT 'c') t

WHERE col NOT IN ('a', 'b')

如果您可以控制列表,我只需要将它们设置为表变量:

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)

如果您可以控制列表,我只需要将它们设置为表变量:

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)
那么:

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)
那么:

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)

我认为您必须将这些值插入到两个变量表中

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')
然后对这两个表执行一些设置操作

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

我认为您必须将这些值插入到两个变量表中

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')
然后对这两个表执行一些设置操作

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
鉴于此功能:

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
或类似于@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'');
可能还有其他各种方式。如果顺序很重要,它会稍微复杂一点,但仍然是可能的。

给定此函数:

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
或类似于@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'');



可能还有其他各种方式。如果顺序很重要,它会稍微复杂一点,但仍然是可能的。

这些列表在您的查询中是硬编码的吗?@stevepastelan是的,它们确实是输出需要是六个独立的列还是可以是字符串?@AaronBertrand string很好!!您是否可以控制列表的脚本编写方式?这些列表在您的查询中是否硬编码?@stevepastelan是的,它们确实是输出需要是六个独立的列还是可以是字符串?@AaronBertrand string很好!!你可以控制列表的脚本编写方式吗?你可能可以使用拆分函数或其他方法将它们作为字符串处理,但我认为这将是最简单的。你对stevepalen Answers有何看法?我认为这不是编译:)他在两个CTE中插入一行,因此它可能也可以工作,但是在每一行之间使用
并集
的语法需要更难看。为什么要使用EXCEPT而不是join?它是一个集合比较运算符,语法更简单。你可以做几个
连接来获得相同的效果,但这更简单。你可以使用拆分函数或其他方法将它们作为字符串处理,但我认为这是最简单的。你对stevepalen Answers有什么看法我认为它不编译:)他在两个CTE中插入一行,因此,它可能也可以工作,但它需要更难看的语法,在每行之间使用
并集
,为什么使用EXCEPT而不是join?它是一个集合比较运算符,语法更简单。你可能会做一些
JOIN
s来获得同样的效果,但这更简单。Msg 156,级别15,状态1,第3行关键字“values”附近的语法不正确。steve你能让它编译吗"? JNK说他将一行插入到两个CTE中,因此它可能也能工作,但需要使用更难看的语法,在每行之间使用并集,这太糟糕了。我手头没有SQL Server,但它是在DB2上运行的。我希望语法是兼容的:)@stevepastelan如果你将
语句更改为
选择“a”联合选择“b”联合…
它应该解析OK。Msg 156,级别15,状态1,第3行关键字“值”附近的语法不正确。steve你能让它编译吗"? JNK说他将一行插入到两个CTE中,因此它可能也能工作,但需要使用更难看的语法,在每行之间使用并集,这太糟糕了。我手头没有SQL Server,但它是在DB2上运行的。我希望语法是兼容的:)@stevepastelan如果您将
语句更改为
select'a'union选择'b'union…
它应该解析OK.+1以进行补偿,尽管您的输出不是与请求相反吗?不。他想要两个列表的异或。不过,感谢同情的投票:-)他说他希望输出是
'b','123','d','e','f','asd'
而不是
'a','c'
。。。他还希望它们是一个字符串,而不是一列中的两个值。集合1由{'a','b'}组成,集合2由{'b','c'}组成。这两个集合的异或是{'a','c'}。将这些值连接回一个字符串是很简单的,但如果需要,我可以添加它。啊,对不起。我认为,一般来说,使用与OP相同的数据更有用,尤其是当您缩减的数据恰好与要求相矛盾时(可能将其更改为
apple、bear、cat
以区分)。+1以补偿,尽管您的输出不是与要求相反吗?不。他想要两个列表的异或。不过,感谢同情的投票:-)他说他希望输出是
'b','123','d','e','f','asd'
而不是
'a','c'
。。。他还希望它们是一个字符串,而不是一列中的两个值。集合1由{'a','b'}组成,集合2由{'b','c'}组成。这两个集合的异或是{'a','c'}。将这些值连接回一个字符串是很简单的,但如果需要,我可以添加它。啊,对不起。一般来说,我认为使用与OP相同的数据更有用,尤其是当您缩减的数据与要求相矛盾时(可能会将其更改为
apple、bear、cat
,以区分)。您为什么使用EXCEPT而不是join?抱歉,交换了代码示例,仅此而已。我只写了所有的东西,除了函数w