简体   繁体   English

如何在select语句中执行多个聚合列

[英]How to do multiple aggregated columns in a select statement

Just to head off the quick-repliers, I'll mention that I'm not using MySQL so I can't use GROUP_CONCAT, and that I've also looked at this question already. 只是为了避开快速回答者,我会提到我没有使用MySQL,所以不能使用GROUP_CONCAT,并且我已经研究了这个问题

The example 这个例子
(this is not the data i'm working with but it accurately describes my case) (这不是我正在使用的数据,但它准确地描述了我的情况)
Person table, with ID, Name columns 人员表,带有ID,名称列
Person_CountriesVisited table, with PersonID, Country columns (1..M linking table) Person_CountriesVisited表,带有PersonID,“国家”列(1..M链接表)
Person_StatesVisited table, with PersonID, State columns (1..M linking table) Person_StatesVisited表,带有PersonID,状态列(1..M链接表)

The constraints 约束条件
I can't modify the DB. 我无法修改数据库。 I can't modify much of the code, either, so this has to be done in SQL, not in code after running the query. 我也不能修改很多代码,因此必须在SQL中完成,而不是在运行查询后在代码中完成。

The desired result 理想的结果
A result set with the columns 具有列的结果集

Person.ID, 人ID
Person.Name, 人名,
[list of related Person_CountriesVisited.Country], [相关的Person_CountriesVisited.Country列表],
[list of related Person_StatesVisited.State], [相关的Person_StatesVisited.State列表],

which can also be filtered by a generic search term which applies across all columns. 也可以通过适用于所有列的通用搜索字词进行过滤。

My attempts 我的尝试

Now, my SQL-fu isn't all that sharp nowadays, but I'm doing what I can based on examples I've found. 现在,我的SQL-fu现在并不那么精明,但是我正在根据发现的示例来做我能做的事情。

1) I've tried using a scalar sub-query: 1)我尝试使用标量子查询:

SELECT P.ID, P.Name, 选择P.ID,P。名称,
( select CV.Country + ', ' (选择CV.Country +','
FROM Person_CountriesVisited CV ON P.ID = CV.PersonId FROM Person_Countries访问的CV ON P.ID = CV.PersonId
FOR XML PATH ('')) AS CountriesVisited, FOR XML PATH(''))AS国家
( SELECT SV.State + ', ' (SELECT SV.State +','
FROM Person_StatesVisited SV ON P.ID = SV.PersonId FROM Person_States访问的SV ON P.ID = SV.PersonId
FOR XML PATH ('')) AS StatesVisited FOR XML PATH(''))AS状态

FROM Person P 从人P

WHERE P.Name LIKE '%' + @SearchTerm + '%' 其中的名称类似'%'+ @SearchTerm +'%'
OR CountriesVisited LIKE '%' + @SearchTerm + '%' 或国家/地区访问喜欢的'%'+ @SearchTerm +'%'
OR StatesVisted LIKE '%' + @SearchTerm + '%' 或州像'%'+ @SearchTerm +'%'

Which returns the data I want, but only when I remove the WHERE clause. 它返回我想要的数据,但是仅当我删除WHERE子句时才返回。 It doesn't work with the WHERE clause because SQL Server 2005 doesn't seem to like that i'm referencing a column created from a scalar subquery in the WHERE clause. 它不适用于WHERE子句,因为SQL Server 2005似乎不喜欢我在WHERE子句中引用从标量子查询创建的列。 It's giving me an "Invalid column name 'CountriesVisited'" error (and again for the StatesVisited column). 这给了我一个“无效的列名'CountriesVisited'”错误(对于StatesVisited列也是如此)。

2) I've tried the cross apply trick: 2)我尝试了交叉应用技巧:

SELECT P.ID, P.Name, CountriesVisited, StatesVisited 选择P.ID,P。名称,国家访问,国家访问

FROM Person P 从人P
INNER JOIN Person_CountriesVisited CV ON P.ID = CV.PersonID INNER JOIN Person_Countries访问的CV ON P.ID = CV.PersonID
CROSS APPLY ( 交叉应用(
SELECT CV.Country + ', ' SELECT CV.Country +','
FROM Person P2 INNER JOIN Person_CountriesVisited CV ON P2.ID = CV.PersonID FROM人员P2内部联接Person_Countries在P2.ID = CV.PersonID上访问的简历
WHERE P.ID = P2.ID P.ID = P2.ID
FOR XML PATH ('') FOR XML路径('')
) PRE_TRIMMED (CountriesVisited) )PRE_TRIMMED(访问国家)

INNER JOIN Person_StatesVisited SV ON P.ID = SV.PersonID 内连接Person_States访问的SV ON P.ID = SV.PersonID
CROSS APPLY ( 交叉应用(
SELECT SV.State + ', ' SELECT SV.State +','
FROM Person P2 INNER JOIN Person_StatesVisited SV ON P2.ID = SV.PersonID FOR XML PATH ('') FROM Person P2内连接Person_States访问的SV ON P2.ID = SV.PersonID FOR XML PATH('')
) PRE_TRIMMED (StatesVisited) )PRE_TRIMMED(状态已访问)

WHERE P.Name LIKE '%' + @SearchTerm + '%' 其中的名称类似'%'+ @SearchTerm +'%'
OR CountriesVisited LIKE '%' + @SearchTerm + '%' 或国家/地区访问喜欢的'%'+ @SearchTerm +'%'
OR StatesVisted LIKE '%' + @SearchTerm + '%' 或州像'%'+ @SearchTerm +'%'

But that doesn't work either since you apparently can't have multiple pre_trimmed calls. 但这也不起作用,因为您显然无法进行多个pre_trimmed调用。

Anybody have suggestions for me? 有人对我有建议吗?

You just need to alias your subqueries: 您只需要别名子查询:

WITH x AS (
  SELECT P.ID
        ,P.Name
        ,( select CV.Country + ', '
         FROM Person_CountriesVisited CV ON P.ID = CV.PersonId 
         FOR XML PATH ('')
        ) AS CountriesVisited
        ,( SELECT SV.State + ', '
         FROM Person_StatesVisited SV ON P.ID = SV.PersonId 
         FOR XML PATH ('')
        ) AS StatesVisited
  FROM Person P
)
SELECT *
FROM X    
WHERE Name LIKE '%' + @SearchTerm + '%'
  OR CountriesVisited LIKE '%' + @SearchTerm + '%'
  OR StatesVisted LIKE '%' + @SearchTerm + '%'

You can do something similar in the second example. 您可以在第二个示例中执行类似的操作。 Actually in the second example, just alias the second subquery as something new, like PRE_TRIMMED2 . 实际上,在第二个示例中,只需将第二PRE_TRIMMED2查询作为新别名(例如PRE_TRIMMED2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM