Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Tsql T-SQL查询一个表,获取是否存在其他表值_Tsql_Sql Server 2005 - Fatal编程技术网

Tsql T-SQL查询一个表,获取是否存在其他表值

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)

我不确定这类查询的名称,因此无法正确搜索。我有两张桌子,桌子A大约有10000行。表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%

数字
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性能声明不正确,
在哪里