在 SQL Server 中,我试图选择没有特定运动的地块。包裹可以有零次或多次移动。第三个表格描述了运动。
我有一些包裹
IF OBJECT_ID('tempdb..#Parcels','U') IS NOT NULL
BEGIN
DROP TABLE #Parcels
END;
CREATE TABLE #Parcels(
Id int
,LocalBarcode nvarchar(50)
,ForeignBarcode nvarchar(50)
)
INSERT INTO #Parcels VALUES (1, 'Sabc1', NULL)
INSERT INTO #Parcels VALUES (2, 'Sabc2', NULL)
INSERT INTO #Parcels VALUES (3, 'Sabc3', 'def1')
INSERT INTO #Parcels VALUES (4, 'xabc', NULL)
与包裹相关的是运动
IF OBJECT_ID('tempdb..#Movements','U') IS NOT NULL
BEGIN
DROP TABLE #Movements
END;
CREATE TABLE #Movements(
ParcelId int
,MovementCode nvarchar(3)
)
INSERT INTO #Movements VALUES (1,'MV1')
INSERT INTO #Movements VALUES (2,'MV1')
INSERT INTO #Movements VALUES (2,'MV2')
INSERT INTO #Movements VALUES (2,'MV3')
INSERT INTO #Movements VALUES (3,'MV1')
INSERT INTO #Movements VALUES (3,'MV2')
INSERT INTO #Movements VALUES (3,'MV3')
在第三个表格中详细描述了这些动作
IF OBJECT_ID('tempdb..#MovementDescriptions','U') IS NOT NULL
BEGIN
DROP TABLE #MovementDescriptions
END;
CREATE TABLE #MovementDescriptions(
MovementCode nvarchar(3)
,MovementDesc nvarchar(4)
)
INSERT INTO #MovementDescriptions VALUES ('MV1','Mov1')
INSERT INTO #MovementDescriptions VALUES ('MV2','Mov2')
INSERT INTO #MovementDescriptions VALUES ('MV3','Mov3');
我想要所有包裹
所以对于上述示例数据,我期待包裹 Sabc1
这是我的尝试(不起作用)
WITH ParcelsWithNoForeignBarcodeAndNoMove2
AS (
SELECT
P.Id AS Id
,P.LocalBarcode AS LocalBarcode
,M.MovementCode
,MD.MovementDesc
,ROW_NUMBER() OVER (
PARTITION BY P.Id
ORDER BY P.LocalBarcode
) AS [RowNumber]
FROM #Parcels P
LEFT JOIN #Movements M ON M.ParcelId = P.Id
LEFT JOIN #MovementDescriptions MD ON MD.MovementCode = M.MovementCode AND MD.MovementDesc = 'Mov2'
WHERE
UPPER(P.LocalBarcode) LIKE 'S%'
AND P.ForeignBarcode IS NULL
AND MD.MovementCode IS NULL
)
SELECT
S.Id
,S.LocalBarcode
FROM ParcelsWithNoForeignBarcodeAndNoMove2 S
WHERE
S.RowNumber = 1
答案 0 :(得分:0)
您正在寻找not exists
。大概也是从您使用 upper
您的排序规则区分大小写。根据您的简单描述,您需要:
select *
from #Parcels p
where p.ForeignBarcode is null
and upper(p.LocalBarcode) like 'S%'
and not exists (
select * from #Movements m
where m.ParcelId=p.Id and m.MovementCode='Mv2'
)
答案 1 :(得分:0)
SELECT P.* FROM
#Parcels P
INNER JOIN (
SELECT ParcelId, COUNT(MovementCode)MovementCode FROM #Movements WHERE MovementCode!='MV2' GROUP BY ParcelId HAVING COUNT(MovementCode)=1
)T ON P.ID=T.ParcelId