Sql 如果内联表的结果集为空,如何不连接该表或返回空值
我有一个查询,返回多个值,所有值都围绕其“交易类型”(可以是卡/现金/支票)分组。有些值是从内联表生成的 所有内联表都返回一个公共列,我可以使用它将它们连接到一个原始表中 然而,在测试过程中有一种可能性被揭示,一些内联表可能什么也不返回,这破坏了我的查询 例如,一个内联表按事务类型返回今年的总销售额,另一个内联表按事务类型返回去年的总销售额 这两个内联表都按事务类型分组,并按事务类型连接到查询的其余部分 在开发过程中,这一切都运行得很好,但在测试期间,我发现如果我们有一个新部门去年没有销售(每个部门使用一个单独的数据库),那么我去年销售的内联表将不会返回任何结果 但由于我在代码中加入了这些内联表,所以我什么也不加入,查询也不返回任何结果 我尝试在内联表上使用左连接,当有数据时,这个左连接查询也可以正常工作 但是,当一些内联表中没有数据(例如去年没有数据)时,左连接查询将永远运行(我在15分钟时取消了它),但原始查询直接返回所有列,但没有数据 所以我可以看到问题所在,我正试图加入一些可能不存在的事情!有人知道我怎么避开这个吗?在下班回家的路上,我的一个想法是返回一个空值并使用COALESCE将其替换为0,但这对连接没有帮助,所以我回到了#1 我希望我提供了足够的信息 --原始查询-- --使用左联接进行查询--Sql 如果内联表的结果集为空,如何不连接该表或返回空值,sql,sql-server,Sql,Sql Server,我有一个查询,返回多个值,所有值都围绕其“交易类型”(可以是卡/现金/支票)分组。有些值是从内联表生成的 所有内联表都返回一个公共列,我可以使用它将它们连接到一个原始表中 然而,在测试过程中有一种可能性被揭示,一些内联表可能什么也不返回,这破坏了我的查询 例如,一个内联表按事务类型返回今年的总销售额,另一个内联表按事务类型返回去年的总销售额 这两个内联表都按事务类型分组,并按事务类型连接到查询的其余部分 在开发过程中,这一切都运行得很好,但在测试期间,我发现如果我们有一个新部门去年没有销售(每个
试试这个。这是原始查询的修改版本,使用SQL Server explicit
JOIN
语法:
您的原始left join版本的性能问题可能是由于查询缓存造成的-我怀疑这两个版本都非常慢,但您一直在运行第一个版本,因此缓存了结果。您运行了第二个,但没有可从中提取的缓存结果
使用内部联接
时,如果可能存在NULL
s,则始终会出现问题,因此需要使用左联接
。如果它仍然永远运行,您需要检查执行计划并查看发生了什么
declare @ToDate datetime,
@FromDate datetime,
@StartYear datetime,
@Active datetime
set @ToDate = '30-nov-2010'
set @FromDate = '1-Jan-2010'
set @StartYear = '1-jan-2010'
set @active = '1-jan-2010'
select SUM(th.total_net_retail_central) as 'Net Purchases TY',
IL2.total_sum as 'Net Purchases LY',
IL3.total_sum as 'Net Purchases YTD',
IL6.total_sum as 'Net Purchases YTD (LY)',
tt.Transaction_type_description as 'Channel',
COUNT(DISTINCT th.customer_id) as 'Number of Customers TY',
IL7.total_sum as 'Number of Customers LY',
IL1.Active as 'Number of Active Customers TY',
COUNT(th.transaction_id) as 'Number of Transactions TY',
IL8.total_sum as 'Number of Transactions LY',
IL4.total_sum as 'Total Number of Units TY',
IL5.total_sum as 'Total Number of Units LY'
FROM
transaction_header th
LEFT JOIN ( SELECT transaction_type, COUNT(DISTINCT customer_id) as 'Active'
from transaction_header
where transaction_date BETWEEN @Active and @ToDate
group by transaction_type) IL1 ON IL1.transaction_type = th.transaction_type
LEFT JOIN ( SELECT SUM(th.total_net_retail_central) as 'total_sum', th.transaction_type
from transaction_header th
where th.transaction_date BETWEEN DATEADD(yy, -1, @FromDate) AND DATEADD(yy, -1, @ToDate)
GROUP BY th.transaction_type) IL2 ON IL2.transaction_type = th.transaction_type
LEFT JOIN ( SELECT SUM(th.total_net_retail_central) as 'total_sum', th.transaction_type
FROM transaction_header th
where th.transaction_date BETWEEN @StartYear AND GETDATE()
GROUP BY th.transaction_type) IL3 ON IL3.transaction_type = th.transaction_type
LEFT JOIN ( SELECT SUM(td.quantity) as 'total_sum', th.transaction_type
from transaction_detail td, transaction_header th
where th.transaction_date BETWEEN @FromDate AND @ToDate AND th.transaction_id = td.transaction_id
GROUP BY th.transaction_type) IL4 ON IL4.transaction_type = th.transaction_type
LEFT JOIN ( SELECT SUM(td.quantity) as 'total_sum', th.transaction_type
from transaction_detail td, transaction_header th
where th.transaction_date BETWEEN DATEADD(yy, -1, @FromDate) AND DATEADD(yy, -1, @ToDate) AND th.transaction_id = td.transaction_id
GROUP BY th.transaction_type) IL5 ON IL5.transaction_type = th.transaction_type
LEFT JOIN ( SELECT SUM(th.total_net_retail_central) as 'total_sum', th.transaction_type
from transaction_header th
where th.transaction_date BETWEEN DATEADD(yy, -1, @StartYear) AND DATEADD(yy, -1, GETDATE())
GROUP BY th.transaction_type) IL6 ON IL6.transaction_type = th.transaction_type
LEFT JOIN ( SELECT COUNT(DISTINCT th.customer_id) as 'total_sum', th.transaction_type
from transaction_header th
where th.transaction_date between DATEADD(yy, -1, @FromDate) AND DATEADD(yy, -1, @ToDate)
GROUP BY th.transaction_type) IL7 ON IL7.transaction_type = th.transaction_type
LEFT JOIN ( SELECT COUNT(th.customer_id) as 'total_sum', th.transaction_type
from transaction_header th
where th.transaction_date between DATEADD(yy, -1, @FromDate) AND DATEADD(yy, -1, @ToDate)
GROUP BY th.transaction_type) IL8 ON IL8.transaction_type = th.transaction_type
INNER JOIN transaction_type tt ON th.transaction_type = tt.transaction_type
WHERE
th.transaction_date Between @FromDate AND @ToDate
GROUP BY
tt.transaction_type_description, IL1.Active, IL2.total_sum, IL3.total_sum, IL4.total_sum, IL5.total_sum, IL6.total_sum, IL7.total_sum, IL8.total_sum
试试这个。这是原始查询的修改版本,使用SQL Server explicit
JOIN
语法:
您的原始left join版本的性能问题可能是由于查询缓存造成的-我怀疑这两个版本都非常慢,但您一直在运行第一个版本,因此缓存了结果。您运行了第二个,但没有可从中提取的缓存结果
使用内部联接
时,如果可能存在NULL
s,则始终会出现问题,因此需要使用左联接
。如果它仍然永远运行,您需要检查执行计划并查看发生了什么
declare @ToDate datetime,
@FromDate datetime,
@StartYear datetime,
@Active datetime
set @ToDate = '30-nov-2010'
set @FromDate = '1-Jan-2010'
set @StartYear = '1-jan-2010'
set @active = '1-jan-2010'
select SUM(th.total_net_retail_central) as 'Net Purchases TY',
IL2.total_sum as 'Net Purchases LY',
IL3.total_sum as 'Net Purchases YTD',
IL6.total_sum as 'Net Purchases YTD (LY)',
tt.Transaction_type_description as 'Channel',
COUNT(DISTINCT th.customer_id) as 'Number of Customers TY',
IL7.total_sum as 'Number of Customers LY',
IL1.Active as 'Number of Active Customers TY',
COUNT(th.transaction_id) as 'Number of Transactions TY',
IL8.total_sum as 'Number of Transactions LY',
IL4.total_sum as 'Total Number of Units TY',
IL5.total_sum as 'Total Number of Units LY'
FROM
transaction_header th
LEFT JOIN ( SELECT transaction_type, COUNT(DISTINCT customer_id) as 'Active'
from transaction_header
where transaction_date BETWEEN @Active and @ToDate
group by transaction_type) IL1 ON IL1.transaction_type = th.transaction_type
LEFT JOIN ( SELECT SUM(th.total_net_retail_central) as 'total_sum', th.transaction_type
from transaction_header th
where th.transaction_date BETWEEN DATEADD(yy, -1, @FromDate) AND DATEADD(yy, -1, @ToDate)
GROUP BY th.transaction_type) IL2 ON IL2.transaction_type = th.transaction_type
LEFT JOIN ( SELECT SUM(th.total_net_retail_central) as 'total_sum', th.transaction_type
FROM transaction_header th
where th.transaction_date BETWEEN @StartYear AND GETDATE()
GROUP BY th.transaction_type) IL3 ON IL3.transaction_type = th.transaction_type
LEFT JOIN ( SELECT SUM(td.quantity) as 'total_sum', th.transaction_type
from transaction_detail td, transaction_header th
where th.transaction_date BETWEEN @FromDate AND @ToDate AND th.transaction_id = td.transaction_id
GROUP BY th.transaction_type) IL4 ON IL4.transaction_type = th.transaction_type
LEFT JOIN ( SELECT SUM(td.quantity) as 'total_sum', th.transaction_type
from transaction_detail td, transaction_header th
where th.transaction_date BETWEEN DATEADD(yy, -1, @FromDate) AND DATEADD(yy, -1, @ToDate) AND th.transaction_id = td.transaction_id
GROUP BY th.transaction_type) IL5 ON IL5.transaction_type = th.transaction_type
LEFT JOIN ( SELECT SUM(th.total_net_retail_central) as 'total_sum', th.transaction_type
from transaction_header th
where th.transaction_date BETWEEN DATEADD(yy, -1, @StartYear) AND DATEADD(yy, -1, GETDATE())
GROUP BY th.transaction_type) IL6 ON IL6.transaction_type = th.transaction_type
LEFT JOIN ( SELECT COUNT(DISTINCT th.customer_id) as 'total_sum', th.transaction_type
from transaction_header th
where th.transaction_date between DATEADD(yy, -1, @FromDate) AND DATEADD(yy, -1, @ToDate)
GROUP BY th.transaction_type) IL7 ON IL7.transaction_type = th.transaction_type
LEFT JOIN ( SELECT COUNT(th.customer_id) as 'total_sum', th.transaction_type
from transaction_header th
where th.transaction_date between DATEADD(yy, -1, @FromDate) AND DATEADD(yy, -1, @ToDate)
GROUP BY th.transaction_type) IL8 ON IL8.transaction_type = th.transaction_type
INNER JOIN transaction_type tt ON th.transaction_type = tt.transaction_type
WHERE
th.transaction_date Between @FromDate AND @ToDate
GROUP BY
tt.transaction_type_description, IL1.Active, IL2.total_sum, IL3.total_sum, IL4.total_sum, IL5.total_sum, IL6.total_sum, IL7.total_sum, IL8.total_sum
我不理解左连接,在那里我可以有空的。但问题是内联表(如IL3)不返回任何内容,因此我有一个从空表到右表中任何内容的左连接。如果我将它们改为右连接,查询会立即运行,但不会得到任何结果。这有意义吗。。如果我使用修改后的查询,它也会“永远”运行。谢谢你的建议。@wesprice-你怎么解释对我来说是没有意义的。如果
LEFT JOIN
到一个没有结果的表,那么这些字段只会得到NULL
。在我上面的查询中,transaction\u header
是您的左侧
表,所有其他的都在右侧
。如果它们是空的,你仍然应该得到你的th
字段。。这是忙碌的一周,昨天我的大脑有点疲劳。。我会重新检查我的查询,看看什么是什么,然后让你知道。我不了解左连接,在那里我可以有空的。但问题是内联表(如IL3)不返回任何内容,因此我有一个从空表到右表中任何内容的左连接。如果我将它们改为右连接,查询会立即运行,但不会得到任何结果。这有意义吗。。如果我使用修改后的查询,它也会“永远”运行。谢谢你的建议。@wesprice-你怎么解释对我来说是没有意义的。如果LEFT JOIN
到一个没有结果的表,那么这些字段只会得到NULL
。在我上面的查询中,transaction\u header
是您的左侧
表,所有其他的都在右侧
。如果它们是空的,你仍然应该得到你的th
字段。。这是忙碌的一周,昨天我的大脑有点疲劳。。我会重新检查我的问题,看看是什么,然后让你知道。
declare @ToDate datetime,
@FromDate datetime,
@StartYear datetime,
@Active datetime
set @ToDate = '30-nov-2010'
set @FromDate = '1-Jan-2010'
set @StartYear = '1-jan-2010'
set @active = '1-jan-2010'
select SUM(th.total_net_retail_central) as 'Net Purchases TY',
IL2.total_sum as 'Net Purchases LY',
IL3.total_sum as 'Net Purchases YTD',
IL6.total_sum as 'Net Purchases YTD (LY)',
tt.Transaction_type_description as 'Channel',
COUNT(DISTINCT th.customer_id) as 'Number of Customers TY',
IL7.total_sum as 'Number of Customers LY',
IL1.Active as 'Number of Active Customers TY',
COUNT(th.transaction_id) as 'Number of Transactions TY',
IL8.total_sum as 'Number of Transactions LY',
IL4.total_sum as 'Total Number of Units TY',
IL5.total_sum as 'Total Number of Units LY'
FROM
transaction_header th
LEFT JOIN ( SELECT transaction_type, COUNT(DISTINCT customer_id) as 'Active'
from transaction_header
where transaction_date BETWEEN @Active and @ToDate
group by transaction_type) IL1 ON IL1.transaction_type = th.transaction_type
LEFT JOIN ( SELECT SUM(th.total_net_retail_central) as 'total_sum', th.transaction_type
from transaction_header th
where th.transaction_date BETWEEN DATEADD(yy, -1, @FromDate) AND DATEADD(yy, -1, @ToDate)
GROUP BY th.transaction_type) IL2 ON IL2.transaction_type = th.transaction_type
LEFT JOIN ( SELECT SUM(th.total_net_retail_central) as 'total_sum', th.transaction_type
FROM transaction_header th
where th.transaction_date BETWEEN @StartYear AND GETDATE()
GROUP BY th.transaction_type) IL3 ON IL3.transaction_type = th.transaction_type
LEFT JOIN ( SELECT SUM(td.quantity) as 'total_sum', th.transaction_type
from transaction_detail td, transaction_header th
where th.transaction_date BETWEEN @FromDate AND @ToDate AND th.transaction_id = td.transaction_id
GROUP BY th.transaction_type) IL4 ON IL4.transaction_type = th.transaction_type
LEFT JOIN ( SELECT SUM(td.quantity) as 'total_sum', th.transaction_type
from transaction_detail td, transaction_header th
where th.transaction_date BETWEEN DATEADD(yy, -1, @FromDate) AND DATEADD(yy, -1, @ToDate) AND th.transaction_id = td.transaction_id
GROUP BY th.transaction_type) IL5 ON IL5.transaction_type = th.transaction_type
LEFT JOIN ( SELECT SUM(th.total_net_retail_central) as 'total_sum', th.transaction_type
from transaction_header th
where th.transaction_date BETWEEN DATEADD(yy, -1, @StartYear) AND DATEADD(yy, -1, GETDATE())
GROUP BY th.transaction_type) IL6 ON IL6.transaction_type = th.transaction_type
LEFT JOIN ( SELECT COUNT(DISTINCT th.customer_id) as 'total_sum', th.transaction_type
from transaction_header th
where th.transaction_date between DATEADD(yy, -1, @FromDate) AND DATEADD(yy, -1, @ToDate)
GROUP BY th.transaction_type) IL7 ON IL7.transaction_type = th.transaction_type
LEFT JOIN ( SELECT COUNT(th.customer_id) as 'total_sum', th.transaction_type
from transaction_header th
where th.transaction_date between DATEADD(yy, -1, @FromDate) AND DATEADD(yy, -1, @ToDate)
GROUP BY th.transaction_type) IL8 ON IL8.transaction_type = th.transaction_type
INNER JOIN transaction_type tt ON th.transaction_type = tt.transaction_type
WHERE
th.transaction_date Between @FromDate AND @ToDate
GROUP BY
tt.transaction_type_description, IL1.Active, IL2.total_sum, IL3.total_sum, IL4.total_sum, IL5.total_sum, IL6.total_sum, IL7.total_sum, IL8.total_sum