我需要从子查询中返回多个结果,并且无法弄清楚。最终结果将在垂直轴上产生人名,基于横轴上的动作类别的各种动作。所以最终结果如下:
----------
**NAME CATEGORY 1 CATEGORY 2**
Smith, John Action 1, Action 2 Action 1, Action 2, Action 3
----------
有没有办法在单个查询中执行此操作?
select
name,
(select action from actionitemtable where actioncategory = category1 and contact = contactid)
from
contact c
inner join actionitemtable a
on c.contactid = a.contactid
如果在该子查询中返回了多个结果,我希望能够将其显示为单个逗号分隔的字符串或操作列表等。
谢谢。
正在使用Microsoft Sql Server 2005。
答案 0 :(得分:9)
我使用用户定义函数执行此任务。 udf创建一个带有与参数匹配的所有元素的分隔字符串,然后从select语句中调用udf,以便为记录集中的每条记录提取分隔列表。
CREATE FUNCTION dbo.ud_Concat(@actioncategory int, @contactid int)
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE @sOutput VARCHAR(8000)
SET @sOutput = ''
SELECT @sOutput = COALESCE(@sOutput, '') + action + ', '
FROM dbo.actionitemtable
WHERE actioncategory=@actioncategory AND contact=@contact
ORDER BY action
RETURN @sOutput
END
SELECT
name,
dbo.ud_Concat(category1, contactid) as contactList
FROM contact c
INNER JOIN actionitemtable a ON c.contactid = a.contactid
答案 1 :(得分:3)
您需要提供有关表格结构以及它们如何相互加入的更多信息。
这是一个关于将多行组合成一列的通用示例:
declare @table table (name varchar(30)
,ID int
,TaskID char(3)
,HoursAssigned int
)
insert into @table values ('John Smith' ,4592 ,'A01' ,40)
insert into @table values ('Matthew Jones',2863 ,'A01' ,20)
insert into @table values ('Jake Adams' ,1182 ,'A01' ,100)
insert into @table values ('Matthew Jones',2863 ,'A02' ,50)
insert into @table values ('Jake Adams' ,2863 ,'A02' ,10)
SELECT DISTINCT
t1.TaskID
,SUBSTRING(
replace(
replace(
(SELECT
t2.Name
FROM @Table AS t2
WHERE t1.TaskID=t2.TaskID
ORDER BY t2.Name
FOR XML PATH(''))
,'</NAME>','')
,'<NAME>',', ')
,3,2000) AS PeopleAssigned
FROM @table AS t1
输出:
TaskID PeopleAssigned
------ --------------------------------------
A01 Jake Adams, John Smith, Matthew Jones
A02 Jake Adams, Matthew Jones
(2 row(s) affected)
答案 2 :(得分:1)
这是非常抽象和复杂的。我最初的反应是“透视查询”,但是我看得越多(在早期的回复中)我就越想:你能把这个传递给应用团队吗?你返回“基础”,他们编写并应用程序代码,使这种问题变得轻而易举。当然,你可以将它压缩到SQL,但这并不能使它成为正确的工作场所。
答案 3 :(得分:1)
根据您的查询,试试这个:
SELECT [Name],
STUFF(
(
SELECT ' ,' + [Action]
FROM [AactionItemTable]
WHERE [ActionCategory] = category1
AND [Contact] = contactid
FOR XML PATH('')
), 1, 2, ''
) AS [AdditionalData]
FROM [Contact] C
INNER JOIN [ActionItemTable] A
ON C.[ContactId] = A.[ContactId]
猜猜这是做你想做的最简单的方法。
编辑:如果找到的子查询中没有操作,则[AdditionalData]
结果将为NULL
。
答案 4 :(得分:0)
您可能需要创建自定义聚合函数。 Microsoft有一篇知识库文章,其中包含示例代码here。
答案 5 :(得分:0)
如果您不介意使用游标,可以编写自己的函数来执行此操作。这是一个适用于Adventureworks示例数据库的示例:
CREATE FUNCTION CommaFunctionSample
(
@SalesOrderID int
)
RETURNS varchar(max)
AS
BEGIN
DECLARE OrderDetailCursor CURSOR LOCAL FAST_FORWARD
FOR
SELECT SalesOrderDetailID
FROM Sales.SalesOrderDetail
WHERE SalesOrderID = @SalesOrderID
DECLARE @SalesOrderDetailID INT
OPEN OrderDetailCursor
FETCH NEXT FROM OrderDetailCursor INTO @SalesOrderDetailID
DECLARE @Buffer varchar(max)
WHILE @@FETCH_STATUS = 0
BEGIN
IF @Buffer IS NOT NULL SET @Buffer = @Buffer + ','
ELSE SET @Buffer = ''
SET @Buffer = @Buffer + CAST(@SalesOrderDetailID AS varchar(12))
FETCH NEXT FROM OrderDetailCursor INTO @SalesOrderDetailID
END
CLOSE OrderDetailCursor
DEALLOCATE OrderDetailCursor
RETURN @Buffer
END
这就是这样一个函数在选择查询中出现的方式:
SELECT AccountNumber, dbo.CommaFunctionSample(SalesOrderID)
FROM Sales.SalesOrderHeader