我有2张桌子
CREATE TABLE Floor (
Id bigint primary key identity(1,1),
Name
)
表分配用作表格
的中间表CREATE TABLE Assignment(
Id bigint primary key identity(1,1),
AccountId bigint,
.
.
FloorId bigint, --foreign key for Id column of floor table
.
.
)
如何选择:
假设:
DECLARE @accountIdsXML XML = '<AccountId>73</AccountId><AccountId>74</AccountId>'
示例:
表值:
Floor Table
Id Name
1 1st Floor
2 2nd Floor
3 3rd Floor
4 4th Floor
5 5th Floor
6 6th Floor
7 7th Floor
8 8th Floor
9 9th Floor
10 10th Floor
Assignment Table
Id AccountId FloorId
1 73 1
1 73 2
1 76 3
1 79 4
1 74 5
1 74 6
1 79 7
选择输出:
Floor table
Id Name
1 1st Floor --matches accountid 73
2 2nd Floor --matches accountid 73
5 5th Floor --matches accountid 74
6 6th Floor --matches accountid 74
8 8th Floor --not in assignment table
9 9th Floor --not in assignment table
10 10th Floor --not in assignment table
我基本上想要选择分配给给定的accountid和unchaigned楼层的楼层。
我设法做了什么
DECLARE @accountIdsXML XML = '<AccountId>73</AccountId><AccountId>74</AccountId>'
DECLARE @accountIdsTable as TABLE (Id BIGINT) --table variable to store accountids to be used in the where in operator.
--insert accountids to the table variable
INSERT INTO @accountIdsTable
SELECT [aid].[Col].value('(.)[1]', 'BIGINT') FROM @accountIdsXML.nodes('/AccountId') as [aid]([Col])
SELECT F.* FROM [Assignment] A RIGHT JOIN [Floor] F ON A.FloorId = F.Id
WHERE (A.AccountId IN(SELECT Id from @accountIdsTable) OR F.Id NOT IN (SELECT FloorId FROM Assignment))
答案 0 :(得分:1)
不要从Assignment中选择,而只选择Floor,然后在第一个WHERE子句中加入它们:
SELECT F.* FROM [Floor] F
WHERE EXISTS
(
SELECT 1 FROM [Assignment] A
INNER JOIN @accountIdsTable AI ON AI.Id = A.AccountId
WHERE A.FloorId = F.Id
)
OR F.Id NOT IN (SELECT FloorId FROM Assignment)