我正在编写查询以从多个表中获取结果它给出了所有列中具有重复值的多行期望我希望那些列是短的并且在单行中显示,这些是我的表
表名:AppUesrs
Id Name Gender
1 Goga M
2 Maja M
3 Phadu M
4 Kaku F
5 Seefa F
表名:AppProducts
Id Name Value
1 Bc090 10
2 Bc080 15
3 Mc070 2
4 Mc100 16
5 Bc110 15
表名:AppOrders
Id Date ExpDate
1 08/9/2014 10/10/2015
2 18/9/2014 08/11/2015
3 20/9/2014 25/12/2015
4 01/10/2014 14/12/2015
5 19/10/2014 15/2/2016
和 表名:ProductOwners
OId PId UId
1 1 2
1 2 2
1 5 2
2 3 5
3 4 4
3 3 4
3 5 4
3 1 4
我正在为它编写查询,并显示这样的数据
select O.Id, P.ProductName, U.Name ,O.Date,O.ExpDate
from AppProductOwners PO, AppProducts P, AppOrders O, AppUsers U
Where PO.AppOrderId = O.Id AND PO.ProductsId = P.Id AND PO.AppUserId = U.Id
它提供了像
这样的数据O.Id P.Name U.Name O.Date O.ExpDate
1 Bc090 Maja 08/9/2014 10/10/2015
1 Bc080 Maja 08/9/2014 10/10/2015
1 Bc110 maja 08/9/2014 10/10/2015
我想要像
这样的数据 O.Id P.Name U.Name O.Date O.ExpDate
1 Bc090,Bc080,Bc110 Maja 08/9/2014 10/10/2015
如果有人帮我写这个问题
如果我像
那样写SELECT O.ID,
PName = STUFF(( SELECT ',' + P.ProductName
FROM AppProductOwners PO
INNER JOIN AppProducts P
ON P.Id = PO.ProductsId
AND U.Id = PO.AppUserId
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, ''),
U.FirstName, U.LastName,
O.Date,
o.ExpDate
FROM AppUsers U
INNER JOIN AppOrders O
ON u.id = O.ID;
它没有显示任何内容,如果我像
那样写SELECT O.ID,
PName = STUFF(( SELECT ',' + P.ProductName
FROM AppProductOwners PO
INNER JOIN AppProducts P
ON P.Id = PO.ProductsId
AND AppUsers.Id = PO.AppUserId
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, ''),
U.FirstName, U.LastName,
O.Date,
o.ExpDate
FROM AppUsers U
INNER JOIN AppOrders O
ON u.id = O.ID;
它给出了错误
Msg 4104, Level 16, State 1, Line 6
The multi-part identifier "AppUsers.Id" could not be bound.
答案 0 :(得分:0)
您可以使用SQL Server XML扩展将行连接到一个列中:
SELECT O.ID,
PName = STUFF(( SELECT ',' + P.Name
FROM PO
INNER JOIN P
ON P.ID = PO.PID
WHERE U.ID = PO.UID
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, ''),
U.Name,
O.Date,
o.ExpDate
FROM U
INNER JOIN O
ON u.id = O.ID;
有关其工作原理的详细说明,请参阅this answer
如果您只想包含PName
不为空的行,那么稍微调整查询以使用CROSS APPLY
可能更容易:
SELECT O.ID,
PName = STUFF(p.PName.value('.', 'NVARCHAR(MAX)'), 1, 1, ''),
U.Name,
O.Date,
o.ExpDate
FROM U
INNER JOIN O
ON u.id = O.ID
CROSS APPLY
( SELECT ',' + P.Name
FROM PO
INNER JOIN P
ON P.ID = PO.PID
WHERE U.ID = PO.UID
FOR XML PATH(''), TYPE
) p (PName)
WHERE p.Pname IS NOT NULL;
<强> Examples on SQL Fiddle 强>
修改强>
我认为我最初误解了您的架构,以及Orders
与Users
的关联方式,我认为这会按要求运作:
SELECT O.ID,
PName = STUFF(p.PName.value('.', 'NVARCHAR(MAX)'), 1, 1, ''),
U.Name,
O.Date,
o.ExpDate
FROM AppUsers AS U
CROSS JOIN AppOrders AS O
CROSS APPLY
( SELECT ',' + P.Name
FROM AppProductOwners AS PO
INNER JOIN AppProducts AS P
ON P.ID = PO.PID
WHERE U.ID = PO.UID
AND O.ID = PO.OID
FOR XML PATH(''), TYPE
) p (PName)
WHERE p.Pname IS NOT NULL;