Sql 通过未按预期运行进行分组
假设我有三个表——Orders、OrderDetails和ProductType——Orders表包含一列Customer。我需要做的是编写一个查询,显示客户列表和每个客户下了多少订单,并按另一列显示和分组,这是一个布尔值,基于特定类型的产品(如电话)是否在订单中 例如,我们可能有:Sql 通过未按预期运行进行分组,sql,sql-server-2008,group-by,Sql,Sql Server 2008,Group By,假设我有三个表——Orders、OrderDetails和ProductType——Orders表包含一列Customer。我需要做的是编写一个查询,显示客户列表和每个客户下了多少订单,并按另一列显示和分组,这是一个布尔值,基于特定类型的产品(如电话)是否在订单中 例如,我们可能有: 客户| NumOrders |包括电话 --------------------------------- 詹姆逊| 3 |是 史密斯| 5 |是 韦伯| 1 |是 亚当斯| 2 | |否 詹姆逊| 1 |否 史密
客户| NumOrders |包括电话
---------------------------------
詹姆逊| 3 |是
史密斯| 5 |是
韦伯| 1 |是
亚当斯| 2 | |否
詹姆逊| 1 |否
史密斯| 7 |否
韦伯| 2 |否
然而,当我尝试为此编写查询时,我得到了多行,其中Customer和IncludesPhone的值相同,NumOrders的值各不相同。为什么会这样?我的问题如下:
从订单中选择客户,将(客户)计算为NumOrders,在(ProductType.Type='Phone')时按大小写,然后选择“是”或“否”作为includephone
结束内部加入订单详细信息内部加入产品类型
按客户分组,键入
按includephone订购,客户
由于您同时对客户
和类型
进行分组,因此您的查询将返回每种类型每名客户的订单数量。如果每个客户只需要一行,则应仅按客户
分组,然后使用类似的方法确定某个客户是否购买了手机:
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,则客户至少购买了一部手机,我们返回“是”。由于您同时对
客户
和类型
进行分组,因此您的查询将返回每个客户每种类型的订单数。如果每个客户只需要一行,则应仅按客户
分组,然后使用类似的方法确定某个客户是否购买了手机:
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,则客户至少购买了一部手机,我们返回“是”。这是因为您按
类型
列进行分组,因此可能存在重复行。例如,对于类型“Email”和“Personal”列includePhone
将为“No”,但当您按Type
分组时,输出中将有两条记录
要解决此问题,可以在group by
子句中使用相同的表达式,或使用子查询或:
在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
这是因为您按
类型
列进行分组,所以可能会有重复的行。例如,对于类型“Email”和“Personal”列includePhone
将为“No”,但当您按Type
分组时,输出中将有两条记录
要解决此问题,可以在group by
子句中使用相同的表达式,或使用子查询或:
在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
将组更改为
GROUP BY Customer,
CASE WHEN (ProductType.Type = 'Phone') THEN 'Yes' ELSE 'No' END
将组更改为
GROUP BY Customer,
CASE WHEN (ProductType.Type = 'Phone') THEN 'Yes' ELSE 'No' END
这个查询应该有效
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
这个查询应该有效
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
您可以尝试以下查询:
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
您可以尝试以下查询:
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
如果您使用OrderDetails加入订单,则COUNT将为您提供订购产品的数量,而不是订单的数量。这就是你所需要的?@BogdanSahlean-S.M的答案正是我所需要的。然后你的问题就错了:“我需要做的是写一个查询,显示客户列表以及每个客户下了多少订单”。您应该重新表述您的问题。如果您使用OrderDetails加入订单,则COUNT将为您提供订购产品的数量,而不是订单的数量。这就是你所需要的?@BogdanSahlean-S.M的答案正是我所需要的。然后你的问题就错了:“我需要做的是写一个查询,显示客户列表以及每个客户下了多少订单”。你应该重新表述你的问题。@AndriyM:我在GROUP BY中没有看到任何别名。请说得更具体一点。很显然,我看到了一些不存在的东西,对不起。@AndriyM:我在GROUP BY中没有看到任何别名。请说得更具体些。很明显我看到了一些不在那里的东西,对不起。