T-SQL查询一个表,得到其他表值的存在与否

时间:2013-03-29 10:24:24

标签: tsql sql-server-2005

我不确定这种类型的查询是什么,所以我一直无法正确搜索它。我有两个表,表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行(虽然这会改变,可能会有数千个)

3 个答案:

答案 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