如何区分来自非匹配记录的null和来自左连接中的非现有记录的null?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何区分来自非匹配记录的null和来自左连接中的非现有记录的null?相关的知识,希望对你有一定的参考价值。
下面的语句创建表,数据和有问题的选择。
目标是当没有custid 1的订单时,我想显示“没有找到任何订单”,如果有custid 1的订单记录而不是电视的订单记录,我想显示'找到订单但不是电视订单' 。在这两种情况下,t.description都将为NULL,但我需要区分两种NULL情况。如何区分它们,以便前两个WHEN语句可以相应地处理每个语句?
CREATE TABLE [dbo].[Customer](
[CustId] [int] NOT NULL,
[CustomerName] [varchar](50) NOT NULL
)
CREATE TABLE [dbo].[Order](
[OrderId] [int] NOT NULL,
[CustId] [int] NOT NULL,
[Description] [varchar](50) NOT NULL
)
INSERT INTO customer (CustId, CustomerName) VALUES
(1, 'John'),
(2, 'Tom')
GO
INSERT INTO [order] (OrderId, CustId, Description) VALUES
(1, 2, 'TV')
go
IF OBJECT_ID('tempdb..#temp') IS NOT NULL
DROP TABLE #temp;
SELECT
'TV' Description INTO #temp
SELECT c.CustId
,t.Description
,o.Description
,CASE
WHEN t.Description IS NULL THEN 'Did not find any orders'
WHEN t.Description IS NULL THEN 'Found order but not TV order'
ELSE 'Found TV Order'
END Status
FROM Customer c
LEFT JOIN [Order] o
ON o.CustId = c.CustId
LEFT JOIN #temp t
ON t.Description = o.Description
WHERE c.CustId = 1
更新:
#temp表具有要搜索的条件。在这种情况下'电视'。
如果您只想显示有关客户的信息,请使用聚合:
SELECT c.CustId,
(CASE WHEN COUNT(o.CustId) = 0
THEN 'Did not find any orders'
WHEN SUM(CASE WHEN o.Description = 'TV' THEN 1 ELSE 0 END) = 0
THEN 'Found order but not TV order'
ELSE 'Found TV Order'
END) as Status
FROM Customer c LEFT JOIN
[Order] o
ON o.CustId = c.CustId
WHERE c.CustId = 1
GROUP BY c.CustId;
请注意,我不知道#temp
用于什么。
此外,如果您希望在客户级别获取信息,则不应在SELECT
中包含订单级信息。
///你可以试试这个。
select a.custid,a.CustomerName,orderid=isnull(b.orderId,0),
description=iif(b.description is null,'Did not Find Any Order',b.description)
from Customer a left join [Order] b on a.custid=b.Custid
这个问题并不完全清楚,但我认为临时表#temp
是您想要查看的描述列表。
所以我可以想到几种不同的方法,例如你可以使用OUTER APPLY
:
select
c.CustId,
t.Description,
case
when o.Description is null then
'Did not find any orders'
when o.Description <> t.Description then
concat('Found order but not ',t.Description,' order')
else
concat('Found ',t.Description,' order')
end as status
from dbo.Customer as c
cross join (
select 'TV' as Description
) as t
outer apply (
select top 1 tt.Description
from dbo.[Order] as tt
where
tt.CustId = c.CustId
order by
case when tt.Description = t.Description then 0 else 1 end
) as o
或者您可以使用左连接和外部应用:
select
c.CustId,
t.Description,
case
when o1.Description is not null then
concat('Found ',t.Description,' order')
when o2.OrderId is not null then
concat('Found order but not ',t.Description,' order')
else
'Did not find any orders'
end as status
from dbo.Customer as c
cross join (
select 'TV' as Description
) as t
left join dbo.[Order] as o1 on
o1.CustId = c.CustId and
o1.Description = t.Description
outer apply (
select top 1 tt.OrderId
from dbo.[Order] as tt
where
tt.CustId = c.CustId and
tt.Description <> t.Description
) as o2
这可能对你有帮助,不确定。
案例陈述:
,case when t.Description = o.Description then 'Found TV Order'
when isnull(t.Description,'No') = isnull(o.Description,'No') then 'Did not find any orders'
when isnull(t.Description,'No') <> isnull(o.Description,'No') then 'Found order but not TV order'
end Status
修改查询:
SELECT c.CustId
,t.Description tdesc
,o.Description odesc
,case when t.Description = o.Description then 'Found TV Order'
when isnull(t.Description,'No') = isnull(o.Description,'No') then 'Did not find any orders'
when isnull(t.Description,'No') <> isnull(o.Description,'No') then 'Found order but not TV order'
end Status
/* ,CASE
WHEN t.Description IS NULL THEN 'Did not find any orders'
WHEN t.Description IS NULL THEN 'Found order but not TV order'
ELSE 'Found TV Order'
END Status */
FROM Customer c
LEFT JOIN [Order] o ON o.CustId = c.CustId
LEFT JOIN #temp t ON t.Description = o.Description
--------------------------- **旧代码低于** --------------- ------------------------------
select CustId,descpt
from
(
SELECT c.CustId
, case when o.Description is null then 'Did not find any orders' end descpt
FROM Customer c
LEFT JOIN [Order] o ON o.CustId = c.CustId ) no_orders
where no_orders.descpt is not null
union
select CustId,descpt
from
(
SELECT c.CustId
, case when o.Description ='TV' then 'Found order for TV ' end descpt
FROM Customer c
LEFT JOIN [Order] o ON o.CustId = c.CustId ) no_orders
where no_orders.descpt is not null
union
select CustId,descpt
from
(
SELECT c.CustId
, case when o.Description <> 'TV' then 'Found order but not TV order' end descpt
FROM Customer c
LEFT JOIN [Order] o ON o.CustId = c.CustId ) no_orders
where no_orders.descpt is not null
首先,我假设订单表中的每个客户都可以存在多条记录。由于您需要知道是否有任何订单,但显然需要结果集,您无法根据所需的描述进行过滤...但如果您按客户(和描述)进行分组并使用计数,则可以函数,这也允许您在Order表中可能有许多记录时返回单个记录。
此外,由于您最终尝试根据两个结果集(电视订单和任何订单)回答两个问题,那么您将需要一些版本的两个查询。有几个选项,但子查询是最简单的。
这是SQL(我为此创建了临时表,并添加了更多记录):
CREATE TABLE [dbo].[Customer](
[CustId] [int] NOT NULL,
[CustomerName] [varchar](50) NOT NULL
)
CREATE TABLE [dbo].[Order](
[OrderId] [int] NOT NULL,
[CustId] [int] NOT NULL,
[Description] [varchar](50) NOT NULL
)
CREATE TABLE [dbo].[FakeTemp](
[Description] [varchar](50) NOT NULL
)
INSERT INTO FakeTemp (Description) VALUES
('TV')
GO
INSERT INTO customer (CustId, CustomerName) VALUES
(1, 'John'),
(2, 'Tom'),
(3, 'Steve')
GO
INSERT INTO [order] (OrderId, CustId, Description) VALUES
(1, 1, 'TV')
go
INSERT INTO [order] (OrderId, CustId, Description) VALUES
(2, 2, 'VCR')
go
INSERT INTO [order] (OrderId, CustId, Description) VALUES
(3, 1, 'VCR')
go
select c.CustomerName, count(OrderId) as TV_Orders
, (select count(OrderID) from [order] where CustId = 1) as All_Orders
from customer c
left outer join [order] o on c.CustId = o.CustId
inner join FakeTemp t on o.Description = t.Description
where c.CustID = 1
group by c.CustomerName, t.Description
这里是小提琴的链接(感谢Roman Pekar让我开始):http://sqlfiddle.com/#!18/eadc3/16/0
我没有做case语句,因为我认为你可以很容易地把它变成输出文本所需的case语句,这显示了更好的结果。
对于那些无法完成案例陈述的人,这里完整的完成了作业问题:
select
CASE
WHEN (select count(OrderID) from orders where CustId = 1) = 0 THEN 'Did not find any orders'
WHEN count(OrderID) = 0 THEN 'Found order but not TV order'
ELSE 'Found TV Order'
End as Status
from customer c
left outer join [orders] o on c.CustId = o.CustId
inner join FakeTemp t on o.Description = t.Description
where c.CustID = 1
group by c.CustomerName, t.Description
以上是关于如何区分来自非匹配记录的null和来自左连接中的非现有记录的null?的主要内容,如果未能解决你的问题,请参考以下文章