Sql 通过未按预期运行进行分组

Sql 通过未按预期运行进行分组,sql,sql-server-2008,group-by,Sql,Sql Server 2008,Group By,假设我有三个表——Orders、OrderDetails和ProductType——Orders表包含一列Customer。我需要做的是编写一个查询,显示客户列表和每个客户下了多少订单,并按另一列显示和分组,这是一个布尔值,基于特定类型的产品(如电话)是否在订单中 例如,我们可能有: 客户| NumOrders |包括电话 --------------------------------- 詹姆逊| 3 |是 史密斯| 5 |是 韦伯| 1 |是 亚当斯| 2 | |否 詹姆逊| 1 |否 史密

假设我有三个表——Orders、OrderDetails和ProductType——Orders表包含一列Customer。我需要做的是编写一个查询,显示客户列表和每个客户下了多少订单,并按另一列显示和分组,这是一个布尔值,基于特定类型的产品(如电话)是否在订单中

例如,我们可能有:

客户| 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中没有看到任何别名。请说得更具体些。很明显我看到了一些不在那里的东西,对不起。