0

假设我有三个表——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

4

5 回答 5

2

将分组更改为

GROUP BY    Customer, 
            CASE WHEN (ProductType.Type = 'Phone') THEN 'Yes' ELSE 'No' END
于 2013-08-15T13:29:02.630 回答
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
于 2013-08-15T13:31:20.767 回答
0

由于您同时对Customer和进行分组Type,因此您的查询返回每种类型的每位客户的订单数。如果您只希望每个客户一行,您应该只分组 by 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,则客户至少购买了一部手机,我们返回“是”。

于 2013-08-15T13:27:54.020 回答
0

那是因为您按Type列分组,所以可能有重复的行。例如,对于“电子邮件”和“个人”类型,列IncludesPhone将是“否”,但是当您分组Type时,输出中将有两条记录。

要解决此问题,您可以在子句中使用相同的表达式group by或使用子查询或公用表表达式

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
于 2013-08-15T13:28:00.243 回答
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
于 2013-08-15T13:53:36.317 回答