如何解决TSQL中包含子表的数据结果表?
我正在处理一个产品页面,我必须一次查询所有数据,其中一列应包含多个值。在这种特殊情况下,它是一个包含多张图片的产品列表。不幸的是,我无法将同一列中的所有图片压缩以稍后对其进行切片,因为数据将在 XML.CONFIG 页面中处理,该页面使用 for-each 处理数据。这就是我所拥有的。
简而言之,我希望是否有一种选择数据的方式,每条记录都有一个“子列表”。
示例...
产品表:
Id ProdId Desc
1 9003 Shirt
2 9004 Trouser
图片表:
Id PicId ProdId
1 A 9003
2 B 9003
3 C 9004
4 D 9004
5 E 9003
查询结果:
ProdId Desc PicId
9003 Shirt
A
B
E
9004 Trouser
C
D
我知道这听起来可能很疯狂,但我记得大约 20 年前,我在一个用于教会管理的 VB 程序中使用 SQL Server Express 和 Crystal Reports 做了类似的事情。我们有一份报告列出了会众成员并将他们的捐款分组在每个成员下面。我确信我所做的一切都是运行一个 SQL 查询来完成这项工作,但那是很久以前的事了,我不记得它是如何完成的。
有什么想法吗?
补充说明:
我只记得当我使用命令“SHAPE”时。我在 T-SQL 文档中找到了一个示例,但不知道为什么它不起作用。我的代码:
SHAPE {SELECT ProdId,Desc FROM product} AS PRO
APPEND ({SELECT PicId FROM pics} AS PIC
RELATE PRO.ProdId TO PIC.ProdId)
这很奇怪。我正在按照示例进行操作,但它说} 附近存在语法错误。
T-SQL 文档: https://docs.microsoft.com/mt-mt/sql/ado/guide/data/shape-append-clause?view=sql-server-2017
解决方法
这是 prodid
上的简单左连接。
SELECT pr.prodid,pr.desc,pi.picid
FROM product pr
LEFT JOIN picture pi
ON pi.prodid = pr.prodid
ORDER BY pr.prodid,pi.picid;
哪个会让你
prodid | desc | left |
---|---|---|
9003 | 衬衫 | A |
9003 | 衬衫 | B |
9003 | 衬衫 | E |
9004 | 裤子 | C |
9004 | 裤子 | D |
其余的是@Larnu 评论的表示层逻辑。每次遇到尚未处理的产品时,您基本上都会遍历结果并打印产品的标题行。无论哪种情况,都打印图片行。
,如果您使用的是 SQL 2017,则可以使用 STRING_AGG 函数。如果没有,那么我将使用 FOR XML 子句,例如:
CREATE TABLE #PRODUCT(Id int,ProdId int,[Desc] varchar(50))
INSERT INTO #PRODUCT VALUES
(1,9003,'Shirt'),(2,9004,'Trouser')
CREATE TABLE #PICTURE(Id int,PicId varchar(4),ProdId int)
INSERT INTO #PICTURE VALUES
(1,'A',9003),'B',(3,'C',9004),(4,'D',(5,'E',9003)
对于 SQL 2017 及更高版本:
select p.id,p.ProdId,STRING_AGG(pt.PicID,CHAR(13)) PicID
from #PRODUCT p
INNER JOIN #PICTURE PT on p.ProdId = pt.ProdId
GROUP BY p.Id,p.ProdId
对于 SQL 2016 及以下版本:
SELECT p.id,STUFF(
(SELECT CHAR(13) + pt.PicID
FROM #PICTURE pt
WHERE p.ProdId = pt.ProdId
FOR XML PATH ('')),1,'') PicID
FROM #PRODUCT p
GROUP BY p.Id,p.ProdId
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。