1

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

4

3 回答 3

4

您可以EXISTS在找到第一行后使用短路,而不是COUNT-ing 所有匹配的行。

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:“我不确定这种类型的查询叫什么”。这将给出一个半连接的计划。有关更多信息,请参阅CASE 表达式中的子查询。

于 2013-03-29T10:26:02.323 回答
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 
于 2013-03-29T10:31:09.007 回答
-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
于 2013-03-29T10:33:28.710 回答