基于值在其他列中的存在而返回值的SQL问题
我有一张这样的桌子:基于值在其他列中的存在而返回值的SQL问题,sql,sql-server,group-by,count,Sql,Sql Server,Group By,Count,我有一张这样的桌子: Location ItemID AlternativeID 20 1234 9999 22 1234 9999 20 9999 22 9999 20 2345 3456 22 2345 20 3456 我正在寻找一个将返回任何项的查询,其中,如果ItemID同时位于位置20和22,并且位置22中不存在替代的idon位置
Location ItemID AlternativeID
20 1234 9999
22 1234 9999
20 9999
22 9999
20 2345 3456
22 2345
20 3456
我正在寻找一个将返回任何项的查询,其中,如果ItemID同时位于位置20和22,并且位置22中不存在替代的idon位置20,则返回ItemID
与上面的一样,它将返回2345,因为它在两个位置都存在,但在位置22上不存在AlternativeID
感觉我已经尝试了很多过于复杂的事情,但是我遗漏了一些明显的东西
编辑:
我想我指定的问题是错误的,所以这里有更多的信息,希望能有所帮助。
AlternativeID要么为空,要么有一个数字,它从不为空
使用上面的示例表,我预期的结果是:
Location ItemID AlternativeID
20 2345 3456
因为这是唯一一个在位置20和22中有文章的条目,而在位置20中有一个在位置22中不存在的备选ID
这是我迄今为止最接近的一次:
SELECT *
FROM [Table] t1
WHERE t1.Location = 20
AND t1.AlternativeID <> ''
AND EXISTS (SELECT 1 FROM [Table] t2 WHERE t2.ItemID
AND NOT EXISTS (SELECT 1 FROM [Table] t2 WHERE t2.ItemID = t1.AlternativeID
AND t2.Location = 22)
您可以使用聚合。我认为你想要的逻辑是:
select itemid
from mytable
where location in (20, 22)
group by itemid
having count(*) = 2 and max(case when location = 22 then alternativeid end) is null
这将为您提供在两个位置都存在的项,并且其在位置22处的alternativeid为null。也许您还想指定位置20处的alternativeid不应为null
选择带有where子句的查询应有助于:
SELECT itemid FROM test
WHERE alternativeid is NOT NULL
AND itemid =(SELECT itemid FROM test WHERE alternativeid is NOT NULL)
您可以使用where exists子句解决此问题 样本数据 解决方案 您可以使用“不存在”作为
这些建议似乎都没有达到我想要的效果,可能是我把问题定义错了。 我让它像这样工作,我想我无论如何都会把答案贴在这里
SELECT t.[LocationID]
,t.[ItemID]
,t.[AlternativeID]
,tt.[LocationID]
,tt.[ItemID]
,tt.[AlternativeID]
FROM [MyTable] t
RIGHT JOIN [MyTable] tt ON t.[ItemID] = tt.[ItemID] AND tt.[LocationID] = 22
WHERE t.[AlternativeID] <> 0
AND t.[LocationID] = 20
AND t.[AlternativeID] NOT IN (SELECT [ItemID] FROM [MyTable] WHERE [LocationID] = 22)
还要指定预期的结果。
declare @data table
(
Location int,
ItemID int,
AlternativeID int
);
insert into @data (Location, ItemID, AlternativeID) values
(20, 1234, null),
(22, 1234, null),
(20, 2345, 3456),
(22, 2345, null),
(20, 3456, null);
select d.ItemID
from @data d
where d.Location = 20 -- items on location 20...
and d.AlternativeID is not null -- ... with an alternative
and exists ( select top 1 'x'
from @data d2
where d2.ItemID = d.ItemID -- ... that have a related row
and d2.Location = 22 -- ... on location 22
and (d2.AlternativeID is null -- ... without alternative
or d2.AlternativeID <> d.AlternativeID) ); -- ... or a different alternative
SELECT *
FROM YourTable T
WHERE Location IN(20, 22)
AND AlternativeID IS NOT NULL
AND NOT EXISTS(
SELECT 1
FROM YourTable TT
WHERE T.Location <> TT.Location
AND T.AlternativeID = TT.AlternativeID
);
SELECT t.[LocationID]
,t.[ItemID]
,t.[AlternativeID]
,tt.[LocationID]
,tt.[ItemID]
,tt.[AlternativeID]
FROM [MyTable] t
RIGHT JOIN [MyTable] tt ON t.[ItemID] = tt.[ItemID] AND tt.[LocationID] = 22
WHERE t.[AlternativeID] <> 0
AND t.[LocationID] = 20
AND t.[AlternativeID] NOT IN (SELECT [ItemID] FROM [MyTable] WHERE [LocationID] = 22)