MSSQL - 使用 IN 连接查询的结果

Posted

技术标签:

【中文标题】MSSQL - 使用 IN 连接查询的结果【英文标题】:MSSQL - Concat the result of a query using IN 【发布时间】:2013-06-05 14:20:05 【问题描述】:

在一个 MSSQL 表(“用户名”)中,我有以下两条记录:

name   ¦  nickname
John      Johny
Marc      Marco

我想做一个查询,当我为 John 和 Marc 的昵称输入 k 时返回“Johny, Marco”。

我尝试了以下方法:

declare @consolidatedNicknames varchar(2000)
set @consolidatedNicknames = ''
select @consolidatedNicknames = @consolidatedNicknames + nickname + ';'
From username WHERE name IN ('John','Marc')

但它只返回“约翰”的昵称。

“约翰”和“马克”的昵称怎么会连在一起?

非常感谢。

【问题讨论】:

搜索"sql server group-concat" 对我来说似乎按预期工作:sqlfiddle.com/#!3/6bfbe/1 @Lamak - 您可能应该向 OP 指出您没有“按原样”使用他/她的脚本。 @PM77-1 什么意思?唯一的区别是我添加了一个SELECT 以查看变量中的值。 @Lamak - 抱歉,我可能误解了 OP 的要求。我以为他希望输出连接的字符串。无论如何,额外的选择就是我的意思。 【参考方案1】:

您的示例代码按预期工作。我在使用大字符串(50k 个字符或更多)的方法时遇到了一些问题。这是一个不同的版本,我发现它更强大。

DECLARE @consolidatedNicknames varchar(2000)
SET @consolidatedNicknames = ''

SELECT @consolidatedNicknames = 
        STUFF((SELECT ', ' + username.nickname
                FROM username
                WHERE name IN ('John','Marc')
                FOR XML PATH(''),TYPE).value('.','VARCHAR(MAX)')
            , 1, 2, '')

【讨论】:

感谢您的快速回复。但是,当我“打印@consolidatedNicknames”时,我只会得到“Marco”,而不是“Johny,Marco”,正如我所期待的那样...... 我猜你的数据有问题。当我们尝试时,您会在几个 cmets 上注意到您现有的代码有效。要么,要么你有一些设置干扰。尝试运行SELECT username.nickname FROM username WHERE name IN ('John','Marc') 看看你会得到什么。 谢谢,我不知道发生了什么,但你说得对,它似乎正在工作!感谢您提供更强大的功能。【参考方案2】:

STUFF 和 XML 是您所需要的。 看看this article

这是我构建的一个函数,用于执行非常相似的操作。

CREATE FUNCTION [dbo].[CapOwnerList]
    (
    @Seperator nvarchar(100) = ','
    )

    RETURNS @ConcatValues TABLE
        (
        ID DECIMAL(28,0) NOT NULL
        ,VALUE NVARCHAR(MAX)
        )
    AS
    BEGIN
        DECLARE @TempTable TABLE (ID INT, VAL VARCHAR(MAX));

        INSERT INTO @TempTable (ID,VAL)
        SELECT  C2O.CAP_ID
                ,FP.NAME
        FROM    REL_CAP_HAS_BUS_OWNER C2O
        INNER JOIN
                FACT_PERSON FP
        ON      C2O.PERSON_ID = FP.ID
        ORDER BY
                FP.NAME
        ;

        IF RIGHT(@Seperator,1)<>' '
            SET @Seperator = @Seperator+' ';

        INSERT @ConcatValues
        SELECT  DISTINCT 
                T1.ID
                ,STUFF((SELECT @Seperator + T2.VAL FROM @TempTable AS T2 WHERE T2.ID = T1.ID FOR XML PATH('')), 1, LEN(@Seperator), '') AS VALS
        FROM    @TempTable AS T1;

        RETURN;
    END

GO

【讨论】:

请注意,使用FOR XML 方法而不使用TYPE).value('.', 'NVARCHAR(MAX),如上述答案将导致特殊字符(例如&gt;)被转义。

以上是关于MSSQL - 使用 IN 连接查询的结果的主要内容,如果未能解决你的问题,请参考以下文章

mssql 数据库“查询处理器用尽了内部资源,无法生成查询计划。”问题的处理

分页结果集中的选择子查询或左外连接哪个更快

MSSQL 详解SQL Server连接(内连接外连接交叉连接)

sql子查询(急100分)

如何从 MSSQL 连接查询中的字段中获取表名? (mysql_field_table 等效)

忽略 PHP 到 MSSQL 连接中的记录行