如何选择子表中没有*特定*记录的所有记录

时间:2021-06-22 09:07:38

标签: sql sql-server tsql

在 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');

我想要所有包裹

  1. 没有外来条码
  2. 本地条码以 S 开头
  3. 包裹没有Mov2运动(包裹可以有其他运动或根本没有运动)

所以对于上述示例数据,我期待包裹 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

2 个答案:

答案 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
相关问题