Tsql T-SQL查询一个表,获取是否存在其他表值
我不确定这类查询的名称,因此无法正确搜索。我有两张桌子,桌子A大约有10000行。表B的行数可变 我想编写一个查询,获取表a的所有结果,但在添加了一列后,该列的值是一个布尔值,表示结果是否也出现在表B中 我已经编写了这个查询,它可以工作,但速度很慢,它不使用布尔值,而是使用零或一的计数。如有任何改进建议,我们将欣然接受:Tsql T-SQL查询一个表,获取是否存在其他表值,tsql,sql-server-2005,Tsql,Sql Server 2005,我不确定这类查询的名称,因此无法正确搜索。我有两张桌子,桌子A大约有10000行。表B的行数可变 我想编写一个查询,获取表a的所有结果,但在添加了一列后,该列的值是一个布尔值,表示结果是否也出现在表B中 我已经编写了这个查询,它可以工作,但速度很慢,它不使用布尔值,而是使用零或一的计数。如有任何改进建议,我们将欣然接受: SELECT u.number,u.name,u.deliveryaddress, (SELECT COUNT(productUserid)
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%
数字
users表中有7366个用户,productUser表中目前有18行(尽管这将发生变化,可能有数千行)您可以使用
EXISTS
在找到第一行后短路,而不是计数所有匹配行
SQL Server没有布尔数据类型。最接近的等价物是位
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:“我不确定这种类型的查询叫什么”。这将给出一个带有半连接的计划。有关详细信息,请参阅。您可以使用EXISTS
在找到第一行后短路,而不是对所有匹配行进行计数
SQL Server没有布尔数据类型。最接近的等价物是位
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:“我不确定这种类型的查询叫什么”。这将给出一个带有半连接的计划。有关这方面的更多信息,请参阅。您使用的是哪种管理系统?
试试这个:
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
您使用的是哪种管理系统?
试试这个:
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
由于您似乎关心性能,因此此查询可以执行得更快,因为这将导致两个表上的索引查找
,而不是索引扫描
:
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
由于您似乎关心性能,因此此查询可以执行得更快,因为这将导致两个表上的索引查找
,而不是索引扫描
:
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
感谢您的快速回复,刚刚尝试了这个,它可以工作,但运行时间与我的版本相似。我能做些什么来优化它吗?另外,谢谢你让我知道它叫什么,当你不知道它的名字时,很难在谷歌上找到它@FullTimeSkeleton-你需要向我们展示你的计划。您可能缺少一个有用的索引。@FullTimeskleton-请为用户和产品用户编写创建表,并将其包含在您的问题中(包括索引)。还可以在SSMS中启用“包含实际执行计划”选项的情况下运行查询,并向我们显示计划。已使用启用的实际执行计划更新问题。不确定如何显示信息。这个查询的所有变体似乎都需要大约2秒的时间才能运行,也许这是我所能期望的最好时间了。@FullTimeSkeleton-您还没有告诉我们您已经有了哪些索引。无论如何,我现在要离线了,但我建议了一个索引,这可能会有所帮助。如果没有,请提供所要求的信息。提供计划的最佳方法是将实际执行计划(未估计)的XML上载到pastebin等托管服务。感谢您的快速回复,我刚刚尝试了这个方法,但它的运行时间与我的版本相似。我能做些什么来优化它吗?另外,谢谢你让我知道它叫什么,当你不知道它的名字时,很难在谷歌上找到它@FullTimeSkeleton-你需要向我们展示你的计划。您可能缺少一个有用的索引。@FullTimeskleton-请为用户和产品用户编写创建表,并将其包含在您的问题中(包括索引)。还可以在SSMS中启用“包含实际执行计划”选项的情况下运行查询,并向我们显示计划。已使用启用的实际执行计划更新问题。不确定如何显示信息。这个查询的所有变体似乎都需要大约2秒的时间才能运行,也许这是我所能期望的最好时间了。@FullTimeSkeleton-您还没有告诉我们您已经有了哪些索引。无论如何,我现在要离线了,但我建议了一个索引,这可能会有所帮助。如果没有,请提供所要求的信息。提供该计划的最佳方法是将实际执行计划(未估计)的XML上传到pastebin等托管服务。说真的,为什么要投反对票?我们需要在性能方面帮助OP(“工作正常,但速度较慢”),查询会给出正确的结果?-1性能声明不正确,其中p.productid=@productid
会将左连接更改回内部连接。是的,但最终聚集索引搜索将否定它。因此,总的来说,性能将优于存在时的情况。这也会因为连接而带来重复。存在时的情况是半联接。在SQL Server中,你声称LOJ比半联接更好地利用索引的说法是不正确的。我反复阅读了OP的查询,经过一些思考,发现它实际上首先不会给出正确的结果,即使不参加我很高兴参加的性能辩论,也总有一些东西可以从中学习。所以我决定删除我的答案,因为它没有真正的价值。但我会把它放在这里一段时间,这样@MartinSmith和FullTimeSkeleton就能看出我承认了我的错误。说真的,为什么要投反对票?我们需要在性能方面帮助OP(“工作正常,但速度较慢”),并且查询会给出正确的结果?-1性能声明不正确,在哪里