选择只有一个订单并且该订单符合某些条件的所有用户

时间:2012-12-05 13:12:53

标签: sql tsql sql-server-2005

我的表包含如下用户:

user_id | status
----------------
1       | 1
2       | 2
3       | 1
4       | 1

包含订单的表

order_id | user_id | status
---------------------------
1        | 1       | 1
2        | 2       | 1
3        | 2       | 2
4        | 2       | 1
5        | 3       | 1

包含订购产品的表格

order_id | cash
----------------
1        | 10
1        | 20
1        | 10
2        | 10
3        | 10
3        | 10

我需要选择的是所有状态= 1并且只有一个订单且该订单必须具有status = 1且该订单的所有产品总和必须> = 30的用户。

因此,对于上述数据,查询应仅返回id = 1

的用户

我设法编写了选择程序,但它没有快速工作:

SELECT user_id
FROM   users US
WHERE  status = 1
       AND (SELECT Count(*)
            FROM   orders ORD
            WHERE  ORD.user_id = US.user_id) = 1
       AND (SELECT Count(*)
            FROM   orders ORD
            WHERE  ORD.user_id = US.user_id
                   AND ORD.status = 1) = 1
       AND (SELECT Sum(PRO.cash)
            FROM   products PRO
                   JOIN orders ORD
                     ON PRO.order_id = ORD.order_id
            WHERE  ORD.user_id = US.user_id) > 30  

我想稍微提高一点,所以我不必使用这么多内心选择

2 个答案:

答案 0 :(得分:4)

通过将查询从where子句移到joins,您通常可以获得更好的性能:

select  u.user_id
from    Users u
join    Orders o
on      o.user_id = u.user_id
join    Producs p
on      p.order_id = o.order_id
group by
        u.user_id
having  min(u.status) = 1 -- there's only 1 user, so min() is safe
        and count(distinct o.order_id) = 1
        and min(o.status) = 1 -- there's only 1 order, so min() is safe
        and sum(p.cash) > 30

答案 1 :(得分:0)

SELECT USER_ID
  FROM (SELECT US.USER_ID, SUM (PRO.CASH) CASH
          FROM USERS US, ORDERS ORD, PRODUCTS PRO
         WHERE US.USER_ID = ORD.USER_ID AND ORD.ORDER_ID = PRO.ORDER_ID AND US.STATUS = 1 AND ORD.STATUS = 1)
 WHERE CASH > 30