【问题标题】:select an xml type column in select query with group by SQL Server 2008在 SQL Server 2008 的分组查询中选择一个 xml 类型列
【发布时间】:2018-03-22 19:59:50
【问题描述】:

我正在编写一个选择查询,其中我正在获取几列(通过连接 3-4 个表)。 我使用 group by 子句对结果进行分组。

查询 -

    select ci.Candidate_Id, ci.FirstName, ci.DetailXML
from Candidate_Instance ci 
where ci.Candidate_Instance_Id=2
group by 
ci.Candidate_Id, ci.FirstName, ci.DetailXML

其中一个表有一个 XML 数据类型的列。当我在选择列表中添加列时,出现此错误 -

选择列表中的“table.myXML”列无效,因为它既不包含在聚合函数中,也不包含在 GROUP BY 子句中。

当我在 group by 子句中添加列时,我收到此错误 -

无法对 XML 数据类型进行比较或排序,除非使用 IS NULL 运算符。

我很困惑如何摆脱这种情况。 我想从列中获取 XML 数据。

谢谢

【问题讨论】:

  • 您能否给我们实际的查询和表结构,以便我们了解您为什么使用GROUP BY?您没有在那里使用任何聚合。 CandidateId 也可以有多个不同的DetailXML 行吗?
  • Martin,我原来的查询很长,解释我的表结构会很不方便。我理解你的意思,但我不能在这里讨论我的数据库结构。我只是想要一个提示/技巧来让事情顺利进行。
  • 如果candidate_id 是candidate_instance 中的主键,这很简单:您可以使用cte 并将cte 连接到选择XML 的表中。这将比公认的答案快得多。

标签: sql-server xml group-by


【解决方案1】:

您不能按 XML 或 TEXT 列分组,您首先需要转换为 varchar(max)

select ci.Candidate_Id, ci.FirstName, convert(xml,convert(varchar(max),ci.DetailXML)) DetailXML
from Candidate_Instance ci 
where ci.Candidate_Instance_Id=2
group by 
ci.Candidate_Id, ci.FirstName, convert(varchar(max),ci.DetailXML)

在第一行,它被转换为 varchar(max) 以匹配 GROUP BY 子句,然后它被重新转换回 XML。

【讨论】:

  • @saarthak - 有趣的是知道它是否真的将其转换为varchar(max),然后对这些巨大的字符串进行排序,或者是否避免这种情况。
【解决方案2】:

根据您的问题中的信息,我不确定您为什么在此处使用group by,但无论如何这都可以工作,因为您似乎只是将其包含在group by 中以便能够@987654323 @它。

;with cte as
(
    select ci.Candidate_Id, 
           ci.FirstName, 
           ci.DetailXML, 
           ROW_NUMBER() OVER (PARTITION by ci.Candidate_Id, ci.FirstName ORDER BY (SELECT 0)) AS RN
    from Candidate_Instance ci  
    where ci.Candidate_Instance_Id=2 
)
SELECT Candidate_Id, FirstName, DetailXML
FROM cte
WHERE RN=1

【讨论】:

  • 嗨马丁,感谢您的回复。我本可以这样管理,但关键是我有一个分组依据的查询,我需要在选择列表中添加一个 XML 类型列。在你的回答中,你能告诉我你会如何在这里使用 group by 吗?
  • 直到我了解GROUP BY 的目的之前。如果您使用它来删除由JOIN 带来的重复项,我可能会以完全另一种方式编写查询。 (例如,使用WHERE EXISTS 而不是JOIN
【解决方案3】:

如果您的表中有任何具有唯一数据的列,您可以使用 CTE,如果该列上有索引,那么什么是快速解决方案:

with cte as 
(
select 
    ci.Candidate_Id, 
    ci.FirstName
from Candidate_Instance ci 
where ci.Candidate_Instance_Id=2
group by 
     ci.Candidate_Id, 
     ci.FirstName
)
select 
    a.*,
    b.DetailXML
from cte a
inner join Candidate_Instance b
on a.Candidate_Id = b.Candidate_Id -- <--this must be unique within Candidate_Instance

【讨论】:

    猜你喜欢
    • 2011-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多