SQL Server-查找已下两种订单的所有客户

时间:2019-04-02 15:42:30

标签: sql sql-server

我正在尝试从一个客户中提取所有未结订单的列表,其中同一客户使用了我们的一种特殊付款类型以及我们的一种标准选项。具体来说,那些具有 预付款或10n30 至少有一个正常订单的未结订单。因此,在下面的示例表中,我想返回order_id 1、3和4。

cust_orders                       order_info
+----------+-----------+          +----------+-------------+----------+
| cust_id  | order_id  |          | order_id |  pay_type   |  status  |
+----------+-----------+          +----------+-------------+----------+
|       1  |         1 |          |       1  | standard    | open     |
|       1  |         2 |          |       2  | prepay      | closed   |
|       1  |         3 |          |       3  | prepay      | open     |
|       1  |         4 |          |       4  | 10n30       | open     |
|       2  |         5 |          |       5  | standard    | deferred |
|       2  |         6 |          |       6  | prepay      | open     |
|       3  |         7 |          |       7  | N/A         | deferred |
|       4  |         8 |          |       8  | prepay      | open     |
|       4  |         9 |          |       9  | standard    | closed   |
|       4  |        10 |          |      10  | prepay      | open     |
+----------+-----------+          +----------+-------------+----------+

我有以下查询

SELECT *
FROM cust_orders AS co
    LEFT JOIN ( SELECT *
              FROM order_info
              WHERE pay_type IN('prepay', '10n30')
              AND status = 'open' ) AS o1 on o1.order_id = co.order_id
    LEFT JOIN ( SELECT *
              FROM order_info
              WHERE pay_type NOT IN('prepay', '10n30')
              AND status = 'open' ) AS o2 on o2.order_id = co.order_id
WHERE o1.order_id IS NOT NULL
     AND o2.order_id IS NOT NULL
ORDER BY co.order_id DESC;

但它运行非常缓慢,并返回一堆重复项。

我看过Search for orders that have two products, one with specific reference, other with specific descriptionSELECT all orders with more than one item and check all items status,但似乎都不是我所需要的。


编辑:感谢gjvdkamp提供了以下代码的基础;我修改了他们的解决方案,以便在更大的查询中使用,并且现在一切正常。

SELECT co.*, [other fields]
FROM cust_order AS co
     LEFT JOIN [other tables]
WHERE cust_id IN ( SELECT co.cust_id
                   FROM cust_order AS co
                        LEFT JOIN order_info o on o.order_id = co.order_id
                   WHERE o.status = 'open'
                   GROUP BY co.cust_id
                   HAVING SUM(CASE WHEN o.pay_type IN ('prepay', '10n30') THEN 1 ELSE 0 END) > 0 
                      AND SUM(CASE WHEN (o.pay_type NOT IN ('prepay', '10n30') OR o.pay_type IS NULL) THEN 1 ELSE 0 END) > 0)

2 个答案:

答案 0 :(得分:2)

“手推式枢轴”在这里可以很好地工作:

select cust_id,
       sum(case when pay_type = 'normal'             then 1 else 0 end) as NormalCount,
       sum(case when pay_type in ('prepay', '10n30') then 1 else 0 end) as OtherCount
from   cust_order co 
       inner join order o on co.order_id = o.order_id 
where  o.status = 'open'
       and o.pay_type in ('normal','prepay','10n30')
group by cust_id
having NormalCount> 0 and 
       OtherCount > 0

这仅需要一个联接(如果您有正确的索引,则合并),然后将其聚集。不知道您的订单表上的统计信息,而是在pay_type上添加了where语句,以便很好地衡量。这将是很难击败速度明智的。

编辑:删除了with语句,因为它甚至不需要

答案 1 :(得分:1)

我认为某些窗口函数可以解决问题:

print(df_new)