【问题标题】:Translating MySQL statement to MS SQL (no GROUP_CONCAT)将 MySQL 语句转换为 MS SQL(无 GROUP_CONCAT)
【发布时间】:2014-07-03 09:48:18
【问题描述】:

我正在尝试从SQL multiple rows as columns (optimizing) 的问题中翻译查询。它在 MySQL 中,但我还需要它在 MS SQL Server 上运行。

一个问题是 MS SQL 中没有 GROUP_CONCAT,但似乎有办法模拟这种情况 (Simulating group_concat MySQL function in Microsoft SQL Server 2005?)。

另外,我找不到将第一个SELECT 语句存储到@sql 变量中的方法,这让我很困扰,因为我不知道如何引用colkey,就像我目前所做的那样.

MySQL 语句:

SET @sql = NULL;

SELECT
    GROUP_CONCAT(DISTINCT
        CONCAT('MAX(CASE
                WHEN ckm.colkey = ', colkey, ' THEN
                    (ccdr.value)
                END) AS ', CONCAT('`ExtraColumn_', colkey, '`'))
    ) INTO @sql
FROM test_customkeymapping;

SET @sql = CONCAT('SELECT c.Name, ', @sql, ' 
                   FROM customers c
                   LEFT JOIN customercustomdatarels ccdr
                     ON c.Id = ccdr.customer
                   LEFT JOIN customdatas cd
                     ON cd.Id = ccdr.customdata
                   LEFT JOIN test_customkeymapping ckm 
                     ON cd.key = ckm.customkey
                   GROUP BY c.Id');

PREPARE stmt FROM @sql;
EXECUTE stmt;

【问题讨论】:

    标签: sql sql-server tsql


    【解决方案1】:

    在 SQL Server 中,您需要进行以下更改

    • 使用类型显式声明变量
    • 使用+ 而非CONCAT 连接字符串(除非您使用的是SQL Server 2012 或更高版本)
    • 对对象名称/别名使用方括号 ([]) 而不是反引号 (``) - QUOTENAME 将为您执行此操作
    • 使用 XML 扩展来连接行
    • c.Name 包含在组中,因为它包含在选择中
    • 使用SP_EXECUTESQL 实际执行您的查询

    所以你的查询变成这样:

    DECLARE @SQL NVARCHAR(MAX);
    
    SET @SQL = 'SELECT c.Name' + (  SELECT  DISTINCT
                                            ', MAX(CASE WHEN ckm.colkey = ' 
                                            + QUOTENAME(colKey AS VARCHAR(10)) 
                                            + ' THEN (ccdr.value) END) AS ' 
                                            + QUOTENAME('ExtraColumn_' + CAST(colKey AS VARCHAR(10))
                                    FROM    test_customkeymapping
                                    FOR XML PATH(''), TYPE
                                ).value('.', 'NVARCHAR(MAX)') + 
                'FROM  customers c
                       LEFT JOIN customercustomdatarels ccdr
                         ON c.Id = ccdr.customer
                       LEFT JOIN customdatas cd
                         ON cd.Id = ccdr.customdata
                       LEFT JOIN test_customkeymapping ckm 
                         ON cd.[key] = ckm.customkey
                       GROUP BY c.ID, c.Name';
    
    EXECUTE SP_EXECUTESQL @SQL;
    

    【讨论】:

    • 谢谢!只需进行一些修改,就可以完美地工作。我不得不删除 colkey 的 QUOTENAME,因为它是一个整数,并将括号添加到 'key' 列,因为它是一个关键字。我已经更新了你的答案。再次...谢谢!
    • 没问题。我已经更新了答案以添加从整数到 varchar 的强制转换,而不是删除引号。
    猜你喜欢
    • 2020-11-23
    • 1970-01-01
    • 2012-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-18
    • 1970-01-01
    相关资源
    最近更新 更多