如何使用 GROUP_CONCAT 正确地将 MySQL 查询转换为 MSSQL 查询

Posted

技术标签:

【中文标题】如何使用 GROUP_CONCAT 正确地将 MySQL 查询转换为 MSSQL 查询【英文标题】:How to correctly translate MySQL query to MSSQL query using GROUP_CONCAT 【发布时间】:2015-06-06 02:42:12 【问题描述】:

我正在尝试将 mysql 数据库转换为 MSSQL 数据库,但在翻译查询时遇到了一些问题,尤其是以下问题:

MySQL

SELECT GROUP_CONCAT( parent.Name
ORDER BY parent.Lft
SEPARATOR  "«" ) AS Path, node.Description
FROM  `DB`.`Categories` AS node,  `DB`.`Categories` AS parent
WHERE node.Lft BETWEEN parent.Lft AND parent.Rgt AND node.ID = 2
GROUP BY node.Name, node.ID
ORDER BY node.Lft LIMIT 1;

而我得到的结果是这个,就是我想要得到的:

+-------------------------------+
| Path                          |
+-------------------------------+
| Master Node « Vehicles « Cars |
+-------------------------------+

MS SQL

我尝试使用这篇文章 https://***.com/a/5981860/2098159 中的建议重新创建 MySQL 查询

SELECT STUFF((SELECT  ' « ' + [Name] FROM [DB].[dbo].[Categories] FOR XML PATH ('')), 1, 1, '') AS [Path] 
FROM [DB].[dbo].[Categories] AS node, [DB].[dbo].[Categories] AS parent 
WHERE node.[Lft] BETWEEN parent.[Lft] AND parent.[Rgt] AND node.[ID] = 7 
GROUP BY node.[Name], node.[ID], node.[Lft] ORDER BY node.[Lft];

而我得到的结果是这样的,无论我选择哪个ID:

+---------------------------------------------+
| Path                                        |
+---------------------------------------------+
| « Master Node « Vehicles « Cars « Computers |
+---------------------------------------------+

此时我只创建了一个包含 4 条记录的表:主节点、车辆、汽车和计算机;只是为了测试。

我不知道我错过了什么。有人有建议吗?

提前致谢。

【问题讨论】:

获得 SQL 答案的最佳方法是创建一个 SQLFiddle。 LIMIT 1 在 SQL Server 中是 TOP(1) ;)。 【参考方案1】:

问题是您缺少 xml 路径部分中的条件:

SELECT 
  STUFF((
    SELECT  ' « ' + [Name] 
    FROM [DB].[dbo].[Categories] C 
    WHERE C.ID = node.ID -- a criteria here is needed to get correct rows
  FOR XML PATH ('')), 1, 1, '') AS [Path] 
FROM 
  [DB].[dbo].[Categories] AS node, 
  [DB].[dbo].[Categories] AS parent 
WHERE 
  node.[Lft] BETWEEN parent.[Lft] AND parent.[Rgt] AND 
  node.[ID] = 7 
GROUP BY 
  node.[Name], 
  node.[ID], 
  node.[Lft] 
ORDER BY 
  node.[Lft];

我的假设是 ID 足以识别正确的行。

【讨论】:

您好,感谢您的友好回复。你说得对,身份证就够了。尽管如此,我添加了您建议的标准,但我只得到了一条记录。例如,如果我使用 ID = 7,我只会得到 « Cars,而不是 Master Node « Vehicles « Cars。再次感谢。【参考方案2】:

在这里我放置了正确的查询。

SELECT STUFF((SELECT CAST(' « ' AS varchar(MAX)) + parent.name
  FROM Categories AS node, Categories AS parent
 WHERE node.[Lft] BETWEEN parent.[Lft] AND parent.[Rgt]
   AND node.[ID] = 7
 ORDER BY node.lft
   FOR XML PATH('')), 1, 1, '') as Path

我唯一不能删除的是第一个“«”

+---------------------------------+
| Path                            |
+---------------------------------+
| « Master Node « Vehicles « Cars |
+---------------------------------+

【讨论】:

以上是关于如何使用 GROUP_CONCAT 正确地将 MySQL 查询转换为 MSSQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

如何正确地将数据帧的所有日期时间列转换为 iso 格式

如何正确使用不同的 group_concat - MYSQL

如何破解 MySQL GROUP_CONCAT 以获取有限数量的行?

如何破解 MySQL GROUP_CONCAT 以获取有限数量的行?

关于group_concat函数拼接字符超长的问题

如何正确地将库与 cmake 链接?