假设我有三个表 - Orders,OrderDetails和ProductType - Orders表包含Customer列。我需要做的是编写一个查询,向我显示一个客户列表和每个客户放置了多少订单,以及显示和分组另一列,这是一个基于特定类型产品的布尔值 - 说,电话 - 在订单中。
例如,我们可能有:
Customer | NumOrders | IncludesPhone
---------------------------------
Jameson | 3 | Yes
Smith | 5 | Yes
Weber | 1 | Yes
Adams | 2 | | No
Jameson | 1 | No
Smith | 7 | No
Weber | 2 | No
但是,当我尝试为此编写查询时,我将获得具有相同Customer和IncludesPhone值的多行,每个行具有不同的NumOrders值。为什么会这样?我的查询如下:
SELECT Customer, COUNT(Customer) AS NumOrders, CASE WHEN (ProductType.Type = 'Phone') THEN 'Yes' ELSE 'No' END AS IncludesPhone
FROM Orders INNER JOIN OrderDetails INNER JOIN ProductType
GROUP BY Customer, Type
Order By IncludesPhone, Customer
答案 0 :(得分:2)
将组更改为
GROUP BY Customer,
CASE WHEN (ProductType.Type = 'Phone') THEN 'Yes' ELSE 'No' END
答案 1 :(得分:1)
此查询应该有效
SELECT Customer, COUNT(Customer) AS NumOrders,
CASE WHEN (ProductType.Type = 'Phone') THEN 'Yes' ELSE 'No' END AS IncludesPhone
FROM Orders INNER JOIN OrderDetails INNER JOIN ProductType
GROUP BY Customer,
CASE WHEN (ProductType.Type = 'Phone') THEN 'Yes' ELSE 'No' END
Order By IncludesPhone, Customer
答案 2 :(得分:0)
由于您要对Customer
和Type
进行分组,因此您的查询会返回每个类型的每个客户的订单数。如果您只需要每个客户一行,则应该只按Customer
分组,然后使用类似的内容来确定给定客户是否购买了手机:
SELECT Customer, COUNT(Customer) AS NumOrders,
CASE
WHEN SUM(CASE WHEN (ProductType.Type = 'Phone') THEN 1 ELSE 0 END) > 0
THEN 'Yes'
ELSE 'No' END AS IncludesPhone
FROM Orders INNER JOIN OrderDetails INNER JOIN ProductType
GROUP BY Customer
Order By IncludesPhone, Customer
内部金额基本上计算每位客户购买的手机数量。如果这大于0,那么客户至少购买了一部手机,我们返回“是”。
答案 3 :(得分:0)
那是因为您按Type
列进行分组,因此可能存在重复的行。例如,类型“电子邮件”和“个人”列IncludesPhone
将为“否”,但当您按Type
分组时,输出中会有两条记录。
要解决此问题,您可以在group by
子句中使用相同的表达式,也可以使用子查询或Common Table Expression:
with cte as (
select
Customer,
case when pt.Type = 'Phone' then 'Yes' else 'No' end as IncludesPhone
from Orders as o
inner join OrderDetails as od -- ???
inner join ProductType as pt -- ???
)
select Customer, IncludesPhone, count(*) as NumOrders
from cte
group by Customer, IncludesPhone
order by IncludesPhone, Customer
在group by
子句中使用相同的表达式:
select
Customer,
case when pt.Type = 'Phone' then 'Yes' else 'No' end as IncludesPhone,
count(*) as NumOrders
from Orders as o
inner join OrderDetails as od -- ???
inner join ProductType as pt -- ???
group by Customer, case when pt.Type = 'Phone' then 'Yes' else 'No' end
答案 4 :(得分:0)
您可以尝试此查询:
SELECT x.Customer,x.NumOrders,
CASE WHEN x.NumOrders>0 AND EXISTS(
SELECT *
FROM Orders o
INNER JOIN OrderDetails od ON ...
INNER JOIN ProductType pt ON ...
WHERE o.Customer=x.Customer
AND pt.Type = 'Phone'
) THEN 1 ELSE 0 END IncludesPhone
FROM
(
SELECT Customer,COUNT(Customer) AS NumOrders
FROM Orders
GROUP BY Customer
) x
Order By IncludesPhone, x.Customer;
或者这个:
SELECT o.Customer,
COUNT(o.Customer) AS NumOrders,
MAX(CASE WHEN EXISTS
(
SELECT *
FROM OrderDetails od
JOIN ProductType pt ON ...
WHERE o.OrderID=od.OrderID -- Join predicated between Orders and OrderDetails table
AND ProductType.Type = 'Phone'
) THEN 1 ELSE 0 END) AS IncludesPhone
FROM Orders o
GROUP BY Customer
ORDER BY IncludesPhone, o.Customer