Equ*_*lsk 3 sql case left-join sql-server-2008
首先,为长篇大论道歉.它看起来真的比它看起来更简单;-)
我正在尝试做一些我认为在概念上很简单的事情,而且我相信我已经完成了大部分工作,但最后一部分是我无法实现而没有错误,我无法弄清楚如何修复.
我有三个相关的表.
订单:
每一行都是一个具有唯一ID的订单,永远不会有重复.
+---------+---------+
| OrderID | Name |
+---------+---------+
| 1 | Order 1 |
| 2 | Order 2 |
| 3 | Order 3 |
+---------+---------+
Run Code Online (Sandbox Code Playgroud)
订单明细:
关系表,其中每一行都是订单上的产品系列.
+---------+-----------+
| OrderID | ProductID |
+---------+-----------+
| 1 | a |
| 2 | b |
| 2 | c |
| 3 | a |
| 3 | b |
| 3 | b |
+---------+-----------+
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,有些订单只有一个产品(1),有些产品会有多个产品(2),有些产品会有重复的产品(3).
产品
每一行都是具有唯一ID的产品,永远不会有重复.
+-----------+-------------+
| ProductID | Description |
+-----------+-------------+
| a | Chicken |
| b | Fish |
| c | Beef |
+-----------+-------------+
Run Code Online (Sandbox Code Playgroud)
我想从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
Run Code Online (Sandbox Code Playgroud)
结果是这样的:
+---------+-----------------+
| Name | Unique Products |
+---------+-----------------+
| Order 1 | 1 |
| Order 2 | 2 |
| Order 3 | 2 |
+---------+-----------------+
Run Code Online (Sandbox Code Playgroud)
我想要的是这个:
+---------+-----------------+
| Name | Unique Products |
+---------+-----------------+
| Order 1 | Chicken |
| Order 2 | Multi |
| Order 3 | Multi |
+---------+-----------------+
Run Code Online (Sandbox Code Playgroud)
我一直试图使用CASE我相信我已经得到了正确的:
CASE WHEN (COUNT(DISTINCT d.ProductId)) > 1 THEN 'Multi' ELSE p.Description END AS 'Products'
Run Code Online (Sandbox Code Playgroud)
但是,除非我添加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 |
+---------+----------+
Run Code Online (Sandbox Code Playgroud)
例如,它应该在一行上说"Order 2 - Multi".这是我不明白的一点.
如果能在这一点上得到一些帮助,它将解决我的问题,我会接受答案.然而...
奖金回合
以上情况很好,但是如果这一点有可能,我会接受这个作为其他人的答案.
我可以连接产品名称吗?我一直在看COALESCE和FOR XML PATH,但我无法将它们绕到我的头都让我甚至不具有任何代码来显示.
结果看起来像这样:
+---------+--------------+
| Name | Products |
+---------+--------------+
| Order 1 | Chicken |
| Order 2 | Fish;Beef |
| Order 3 | Chicken;Fish |
+---------+--------------+
Run Code Online (Sandbox Code Playgroud)
如果你已经做到这一点,我推荐你!谢谢!
你很近.您只需要描述一些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
Run Code Online (Sandbox Code Playgroud)
第二部分是一个非常不同的问题.在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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
62 次 |
| 最近记录: |