Sql 选择只有一个订单且该订单满足某些条件的所有用户
我有一个包含如下用户的表:Sql 选择只有一个订单且该订单满足某些条件的所有用户,sql,tsql,sql-server-2005,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 |
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并且只有一个订单的所有用户,并且该订单的状态必须为1,并且该订单的所有产品的总和必须大于等于30
所以对于上面的数据查询,应该只返回id=1的用户
我已成功编写了select过程,但运行速度不快:
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
我想对此做一点改进,这样我就不必使用太多的内部选择您通常可以通过将查询从
where
子句移动到joins
来获得更好的性能:
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
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
通常,通过将查询从
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
我喜欢你用副词来回答这个问题。OP还对“恰好一个订单”和“状态=1”进行了限制。这将返回一个用户两个订单,其中一个订单的状态=0,另一个订单的状态=1I,就像您使用subselect来回答问题一样。OP也有“恰好一个订单”和“状态=1”的约束。这将返回一个用户两个订单,其中一个订单的状态=0,另一个订单的状态=1+1。子选择反映了对OP约束的良好理解。了解了使用min作为having子句的一些内容。我甚至没有想过用这种方式执行查询:)我马上检查:)+1子选择反映了对OP约束的良好理解。了解了如何使用min作为having子句。我甚至没有想过用这种方式执行查询:)我马上检查:)