1

我更喜欢使用集合逻辑而不是用游标或其他东西遍历表,但如果这是需要的话,它可以完成。

我基本上是在存储过程中准备一个视图,它将在其他地方用于 BI。现在,存储过程只是从具有相当数量的连接和其他随机逻辑的各种表中提取的选择语句。

这是有关表格外观的示例。首先,将返回的表,其次是用户想要排除的内容。 例子

我想查看 excludes 表中的每条记录,然后将其作为过滤器应用于第一个表,因此它将消除项目匹配的所有行。(它会变得有点复杂,因为他们可以选择消除整个 LocationCode,然后将级联到所有 WarehouseCodes 和它下面的所有东西。它基本上是一个层次结构。但我想把大致的想法记下来)。

我不确定如何使用 NOT EXISTS 来做到这一点,因为我必须逐行进行。我不确定我是否必须使用游标或以另一种方式迭代。我想知道 SQL 中是否还有其他我不知道的工具。

任何关于如何有效地消除基于另一个表值的行的建议将不胜感激,谢谢。

4

3 回答 3

1

如果您想从 Table1 中获取整行,除了 Table2 中具有相似性的行,您可以执行以下操作:

select * -- Column list here
from Table1 as t
where
    not exists (
        select t.LocationCode, t.WarehouseCode, t.WarehouseName, t.StorageAddress
        intersect
        select t2.LocationCode, t2.WarehouseCode, t2.WarehouseName, t2.StorageAddress
        from Table2 as t2
    )

或更方便

select * -- Column list here
from Table1 as t
where
    not exists (
        select *
        from Table2 as t2
        where
            t2.LocationCode = t.LocationCode and
            t2.WarehouseCode = t.WarehouseCode and
            t2.WarehouseName = t.WarehouseName and
            t2.StorageAddress = t.StorageAddress
    )
于 2013-10-01T13:55:43.933 回答
0

查看EXCEPT子句,它的作用类似于UNION

select col1, col2, col3 from yourtable
EXCEPT
select col1, col2, col3 from exceptions
于 2013-10-01T13:44:35.447 回答
0

这里有两件事要解决。在第一种情况下,您已经解释了 Exclude 表的列数与实际表中的列数相同。我在这里假设此表中的某些列将是“可以为 NULL”的,而有些列可能不是。因此,在排除期间,您也需要注意这一点。由于性能原因,我看到“左连接”是一个很好的候选者,而且您只能在需要时对选定的列执行 MATCHING。在您的情况下,现在似乎所有列都需要匹配,但请考虑将来是否在表中添加了 Identity/datetime/timestamp 之类的列。请参阅下面的代码。如果此表中的数据量很大,则适当的非集群和/或过滤索引将帮助您提高性能,但如果您看到视图查询很慢,那是在稍后阶段。

对于您提到的第二部分,稍后您可能会决定完全排除位置代码并且存在分层依赖关系。我会说保持这个分开,直到你有确切的要求。

    DECLARE @AllData TABLE
    (
        ID      INT         NOT NULL PRIMARY KEY
        ,FName  sysname     NOT NULL
        ,LName  sysname     NOT NULL
        ,MName  sysname     NULL
    )

    DECLARE @ExcludeData TABLE
    (
        ID      INT         NOT NULL PRIMARY KEY
        ,FName  sysname     NOT NULL
        ,LName  sysname     NOT NULL
        ,MName  sysname     NULL
    )

    INSERT INTO @AllData( ID, FName, LName, MName )
                SELECT 1,'Fname1','Lname1','MName1'
    UNION ALL   SELECT 2,'Fname2','Lname2',NULL
    UNION ALL   SELECT 3,'Fname3','Lname3','Mname3'
    UNION ALL   SELECT 4,'Fname4','Lname4',NULL

    INSERT INTO @ExcludeData( ID, FName, LName, MName )
                SELECT 1,'Fname1','Lname1','MName1'
    UNION ALL   SELECT 2,'Fname2','Lname2',NULL

    SELECT a.ID,a.FName,a.LName,a.MName
    FROM @AllData a
    LEFT JOIN @ExcludeData b
    ON 
        ((a.ID=b.ID) OR (a.id IS NULL AND b.id IS NULL))
        AND
        ((a.FName=b.FName) OR (a.FName IS NULL AND b.FName IS NULL))
        AND
        ((a.LName=b.LName) OR (a.LName IS NULL AND b.LName IS NULL))
        AND
        ((a.MName=b.MName) OR (a.MName IS NULL AND b.MName IS NULL))
    WHERE 
        (b.ID IS NULL AND b.FName IS NULL AND b.LName IS NULL AND b.MName IS NULL)
于 2013-10-01T14:14:08.993 回答