我对这种情况有问题: 这是课程表 我有这个数据框: 我的预期结果是: 我试过使用 while、for 循环和 if else。 但我认为这是因为错误的位置或对代码的理解: 谢谢你的帮助! ...
提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供 中文繁体 英文版本 中英对照 版本,有任何建议请联系yoyou2525@163.com。
我有三个具有以下结构的表(商店,销售和产品):
--Stores
IdStore StoreName
1A Store A
2B Store B
3C Store C
-- Products
IdProduct Desc
1G Product 1
2A Product 2
3A Product 3
4A Product 4
--Sales
TicketNo Store Product Qty
1001 Store A Product 1 10
1002 Store A Product 1 10
1003 Store B Product 3 50
1004 Store A Product 2 20
1005 Store A Product 3 5
1006 Store B Product 1 30
目前,我有以下查询:
SELECT S.StoreName, sum(SA.Qty), P.Desc
FROM SALES SA
cross apply (select top 1 * from Stores S where SA.Store = S.StoreName) S
cross apply (select top 1 * from Products P where SA.Product = P.Desc) P
group by S.StoreName, P.Desc
根据上面的表结构和数据,查询结果如下:
-- output
StoreName Qty Desc
Store A 20 Product 1
Store A 20 Product 2
Store A 5 Product 3
Store B 30 Product 1
Store B 20 Product 2
我的问题是,是否存在一种获得相同结果但顺序不同的方法,以及是否有可能从一行中的一个商店中获取所有结果,如下所示:
Store Product 1 Product 2 Product 3
Store A 20 20 5
Store B 30 20 0
或类似的东西:
Store Result (in same line)
Store A 20;20;5;
Store B 30;20;0;
首先,您应该使用INNER JOIN
而不是CROSS APPLY:
SELECT S.StoreName, P.Desc,sum(SA.Qty) as QTY
FROM SALES SA
INNER JOIN Stores S ON SA.Store = S.StoreName
INNER JOIN Products P ON SA.Product = P.Desc
group by S.StoreName, P.Desc
如果预先知道列数,则可以使用PIVOT运算符将行转换为列:
SELECT S.StoreName, [Product 1], [Product 2], [Product 3]
FROM
( SELECT SA.StoreName, P.Desc,SA.Qty
FROM SALES SA
INNER JOIN Stores S ON SA.Store = S.StoreName
INNER JOIN Products P ON SA.Product = P.Desc
) Q
PIVOT
(
SUM(Qty)
FOR Q.Desc IN ([Product 1], [Product 2], [Product 3])
) AS pvt
ORDER BY StoreName
坦率地说,在客户端上生成适当的表可能会更容易。 PIVOT无法处理任意数量的列。 另一方面,在ASP.NET中,可以使用LINQ等按商店和产品对数据进行分组,然后根据该数据生成表行。 如果使用了像Entity Framework这样的ORM,则数据将已经处于适当的结构中。
生成所需表可以使用两个循环,例如:
<thead>
<tr>
<th>Store Name</th>
<th>Product 1</th>
...
</tr>
</thead>
@foreach(var store in Model.Stores)
{
<tr>
<td>@store.StoreName</td>
@foreach(var product in store.Products.OrderBy(p=>p.Desc))
{
<td>@product.Qty</td>
}
</tr>
}
您可以使用LINQ获得所有产品名称,例如:
var productNames = Stores.SelectMany(store=>store.Products)
.Select(p=>p.Desc)
.Distinct()
.OrderBy(desc=>desc)
.ToArray();
并使用它们在循环中自己生成标头
干得好。 您将需要PIVOT
功能,但是您需要定义产品的名称。
请参见下面的样机:
DECLARE @Stores TABLE(IdStore VARCHAR(100),[StoreName] VARCHAR(100));
INSERT INTO @Stores
--Stores
select '1A','Store A' UNION ALL
select '2B','Store B' UNION ALL
select '3C','Store C'
DECLARE @Products TABLE(IdProduct VARCHAR(100),[Desc] VARCHAR(100));
INSERT INTO @Products
-- Products
select '1G','Product 1' UNION ALL
select '2A','Product 2' UNION ALL
select '3A','Product 3' UNION ALL
select '4A',' Product 4'
DECLARE @Sales TABLE(TicketNo INT, Store VARCHAR(100),[Product] VARCHAR(100), Qty INT);
INSERT INTO @Sales
--Sales
select '1001','Store A','Product 1','10' UNION ALL
select '1002','Store A','Product 1','10' UNION ALL
select '1003','Store B','Product 3','50' UNION ALL
select '1004','Store A','Product 2','20' UNION ALL
select '1005','Store A','Product 3','5' UNION ALL
select '1006','Store B','Product 1','30'
SELECT p.*
FROM
(
SELECT S.StoreName, SA.Qty, P.[Desc]
FROM
@SALES SA
left join @Stores S on SA.Store = S.StoreName
left join @Products P on SA.Product = P.[Desc]
)t
PIVOT
(
SUM(Qty) FOR [Desc] IN ([Product 1],[Product 2],[Product 3] /*add as many as you need*/)
)p;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.