首先,为长篇帖子道歉。它看起来真的很简单; - )
我正在尝试做一些我认为在概念上很简单的事情,而且我相信我在那里的大部分方式,但最后一部分是我无法实现而没有错误,我无法弄清楚如何修复。
我有三张相关的表格。
订单:
每行都是一个具有唯一ID的订单,永远不会有重复。
+---------+---------+
| OrderID | Name |
+---------+---------+
| 1 | Order 1 |
| 2 | Order 2 |
| 3 | Order 3 |
+---------+---------+
订单明细:
关系表,其中每一行都是订单上的产品系列。
+---------+-----------+
| OrderID | ProductID |
+---------+-----------+
| 1 | a |
| 2 | b |
| 2 | c |
| 3 | a |
| 3 | b |
| 3 | b |
+---------+-----------+
正如您所看到的,一些订单只有一个产品(1),有些产品会有多个产品(2),有些产品会有重复产品(3)。
产品
每行都是具有唯一ID的产品,永远不会有重复。
+-----------+-------------+
| ProductID | Description |
+-----------+-------------+
| a | Chicken |
| b | Fish |
| c | Beef |
+-----------+-------------+
我想从Orders表中返回所有行,并在一列中有条件地返回有关相关产品的一些信息。
条件是我查看每个订单有多少DISTINCT
个产品。如果它只是1,那么我想返回产品描述值。如果它超过1,那么我想返回一些占位符文本,例如“Multi”。
我认为我需要使用CASE
来实现这一点,但我无法理解。
我可以像这样成功地计算出独特的产品:
SELECT
o.Name
,COUNT(DISTINCT d.ProductId) as 'Unique Products'
FROM Orders o
LEFT JOIN OrderDetails d ON o.OrderID = d.OrderID
LEFT JOIN Products p on d.ProductId = p.ProductId
GROUP BY o.Name
ORDER BY o.Name DESC
GO
结果如下:
+---------+-----------------+
| Name | Unique Products |
+---------+-----------------+
| Order 1 | 1 |
| Order 2 | 2 |
| Order 3 | 2 |
+---------+-----------------+
我想要的是:
+---------+-----------------+
| Name | Unique Products |
+---------+-----------------+
| Order 1 | Chicken |
| Order 2 | Multi |
| Order 3 | Multi |
+---------+-----------------+
我一直在尝试使用CASE
,我相信我已经做对了:
CASE WHEN (COUNT(DISTINCT d.ProductId)) > 1 THEN 'Multi' ELSE p.Description END AS 'Products'
但是,除非我将p.Description添加到GROUP BY
,否则我会收到错误(我理解):
列'Product.Description'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。
但如果我添加它,结果就不是我想要的,例如:
+---------+----------+
| Name | Products |
+---------+----------+
| Order 1 | Chicken |
| Order 2 | Fish |
| Order 2 | Beef |
| Order 3 | Chicken |
| Order 3 | Fish |
| Order 3 | Fish |
+---------+----------+
例如,它应该在一行上说“Order 2 - Multi”。 这是我不理解的一点。
如果可以单独获得这方面的帮助,它将解决我的问题,我会接受答案。然而...
奖金回合
以上情况很好,但如果这一点可行,我会接受这个作为其他人的答案。
我可以连接产品名称吗?我一直在关注COALESCE
和FOR XML PATH
,但我根本无法绕过它们,所以我甚至没有任何代码可以显示。
结果看起来像这样:
+---------+--------------+
| Name | Products |
+---------+--------------+
| Order 1 | Chicken |
| Order 2 | Fish;Beef |
| Order 3 | Chicken;Fish |
+---------+--------------+
如果你已经做到这一点,我推荐你!谢谢!
答案 0 :(得分:5)
你非常接近。您只需要一些case
逻辑和围绕描述的聚合函数:
SELECT o.Name,
(CASE WHEN COUNT(DISTINCT d.ProductId) = 1
THEN MAX(p.description)
ELSE 'Multi'
END) as Descriptions
FROM Orders o LEFT JOIN
OrderDetails d
ON o.OrderID = d.OrderID LEFT JOIN
Products p
ON d.ProductId = p.ProductId
GROUP BY o.Name
ORDER BY o.Name DESC
第二部分是一个非常不同的问题。在SQL Server中,您需要使用XML子查询:
select o.Name,
stuff((select distinct ',' + p.description
from OrderDetails d left join
Products p
on d.ProductId = p.ProductId
where o.OrderID = d.OrderID
for xml path (''), type
).value('.', 'nvarchar(max)'
), 1, 1, ''
) as descriptions
from Orders o
order by o.Name desc