我有一个Item表:
Id | Title | Active
====================
1 | Item 1 | 1
2 | Item 2 | 1
A位置表:
Id | Name
=========
1 | A1
2 | B1
和一个链接表,其中EventId指定循环计数事件:
Id | EventId | ItemId | LocationId
=============|====================
1 | 1 | 1 | 2
2 | 1 | 2 | 1
3 | 2 | 1 | 1
4 | 2 | 2 | 2
5 | 3 | 1 | 1
我需要确定哪些项目没有为指定的EventId进行循环计数(在本例中,EventId 3为ItemId 2(。我们使用的代码生成工具只支持带有简单筛选器的表和视图,所以我不能使用存储过程或表值函数。理想情况下,我们希望这样做:
SELECT [EventId], [ItemId] FROM [SomeView] WHERE [EventId] = 3
并得到类似的结果
EventId | ItemId
================
3 | 2
我试着对此进行思考,但没有成功,因为我知道很难质疑否定。这可能吗?
您想要的是以下内容吗?
select l.eventId, x.Id ItemId
from Link l
cross apply (
select *
from Items i
where i.Id != l.ItemId
)x
where l.EventId = 3;
--data to work with
DECLARE @items TABLE (ID int, Title nvarchar(100), Active int)
INSERT INTO @items VALUES (1, 'Item 1', 1)
INSERT INTO @items VALUES (2, 'Item 2', 1)
DECLARE @location TABLE (ID int, Name nvarchar(100))
INSERT INTO @location VALUES (1, 'A1')
INSERT INTO @location VALUES (2, 'B1')
DECLARE @linkTable TABLE (ID int, EventId int, ItemId int, LocationId int)
INSERT INTO @linkTable VALUES (1, 1, 1, 2)
INSERT INTO @linkTable VALUES (2, 1, 2, 1)
INSERT INTO @linkTable VALUES (3, 2, 1, 1)
INSERT INTO @linkTable VALUES (4, 2, 2, 2)
INSERT INTO @linkTable VALUES (5, 3, 1, 1)
INSERT INTO @linkTable VALUES (6, 4, 2, 1)
--query you want
SELECT 3 as EventID, ID as ItemID
FROM @items i
WHERE ID not in (SELECT ItemId
FROM @linkTable
WHERE EventId = 3)
从LinkTable中获取所有ItemID,然后从items表中获取没有同步事件的所有项目。您可以将WHERE
和SELECT
子句中的3替换为您要查找的任何事件。如果你想要所有这样的事件+项目对,那么这应该做到:
SELECT subData.EventId, subData.ItemID
FROM (SELECT i.ID as ItemID, cj.EventId
FROM @items i CROSS JOIN (SELECT DISTINCT EventId
FROM @linkTable) cj) subData
left join @linkTable lt ON lt.EventId = subData.EventId and lt.ItemId = subData.ItemID
WHERE lt.ID is null
这可能会影响性能,因为CROSS JOIN
和DISTINCT
以及子联接,但它可以完成任务。首先,您创建了所有可能的项目和事件对的数据,然后将链接表左键联接到该数据,如果链接表的ID为null,则意味着没有事件+项目对,这意味着该项目没有为该事件同步。