我不确定这种类型的查询是什么,所以我一直无法正确搜索它。我有两个表,表A有大约10,000行。表B具有可变的行数。
我想编写一个获取表A结果的查询但是添加了一列,该列的值是一个布尔值,表示结果是否也出现在表B中。
我写过这个有效但速度慢的查询,它不使用布尔值,而是使用零或一个计数。我们非常感谢任何建议的改进:
SELECT u.number,u.name,u.deliveryaddress,
(SELECT COUNT(productUserid)
FROM ProductUser
WHERE number = u.number and productid = @ProductId)
AS IsInPromo
FROM Users u
更新
我在启用实际执行计划的情况下运行查询,我不确定如何显示结果,但各种成本是:
嵌套循环(左半连接):29%]
聚集索引扫描(用户表):41%
聚集索引扫描(ProductUser表):29%
NUMBERS users表中有7366个用户,而productUser表中当前有18行(虽然这会改变,可能会有数千个)
答案 0 :(得分:4)
您可以在找到第一行后使用EXISTS
短路,而不是COUNT
所有匹配的行。
SQL Server没有布尔数据类型。最接近的等价物是BIT
SELECT u.number,
u.name,
u.deliveryaddress,
CASE
WHEN EXISTS (SELECT *
FROM ProductUser
WHERE number = u.number
AND productid = @ProductId) THEN CAST(1 AS BIT)
ELSE CAST(0 AS BIT)
END AS IsInPromo
FROM Users u
RE:“我不确定这种类型的查询是什么”。这将给出一个半连接的计划。有关详情,请参阅Subqueries in CASE Expressions。
答案 1 :(得分:1)
您使用的是哪种管理系统? 试试这个:
SELECT u.number,u.name,u.deliveryaddress,
case when COUNT(p.productUserid) > 0 then 1 else 0 end
FROM Users u
left join ProductUser p on p.number = u.number and productid = @ProductId
group by u.number,u.name,u.deliveryaddress
UPD:使用mssql
可能会更快;with fff as
(
select distinct p.number from ProductUser p where p.productid = @ProductId
)
select u.number,u.name,u.deliveryaddress,
case when isnull(f.number, 0) = 0 then 0 else 1 end
from Users u left join fff f on f.number = u.number
答案 2 :(得分:-1)
由于您似乎对性能感到担忧,因此此查询可以更快地执行,因为这会导致两个表与index seek
上的index scan
:
SELECT u.number,
u.name,
u.deliveryaddress,
ISNULL(p.number, 0) IsInPromo
FROM Users u
LEFT JOIN ProductUser p ON p.number = u.number
WHERE p.productid = @ProductId