SQL Server WHERE子句中AND和OR的多个条件

fjaof16o  于 2023-01-12  发布在  SQL Server
关注(0)|答案(2)|浏览(260)

我在Microsoft SQL Server Management Studio中工作。我正在使用多个表和多个条件(近80个),我正在查询这些条件,试图获得联接数据的子集。
其思想是,我需要从一个连接中获取数据,而该数据根据条件不在另一个连接中(例如,NOT IN),那么我需要过滤一堆条件,这些条件涉及多列,并且每列都有多个条件。(我认为)是由OR条件引起的。我有一个列,比如col5,如果它不满足AND条件中的任何一个条件,那么我需要进一步过滤它(因此,为OR条件)。
到目前为止我所写的如下,

SELECT 
    handfulOfColumns
FROM 
    table1 AS t1
LEFT JOIN
    (SELECT *
     FROM table2
     WHERE col2 = 'thing0' or col2 = 'thing1') AS t2 ON t1.col1 = t2.col1
WHERE 
    t1.col1 NOT IN (SELECT t1.col1
                    FROM table1 t1
                    LEFT JOIN table3 t3 ON t1.col1 = t3.col1
                    WHERE col3 LIKE '%thing3%')
    AND (col4 > '#' AND col5 NOT LIKE 'thing4' 
         AND col5 != 'thing5' AND col5 NOT LIKE 'thing6' 
         AND col6 NOT LIKE 'thing7'
         --...
         --... add like 20 lines of conditions similar to above
         --...
         AND col34 NOT LIKE 'thing77' AND LEN(col35) > '#')
     OR (col5 NOT LIKE '% %' AND col5 LIKE '%[a-z]%' 
         AND col5 NOT LIKE '%[0-9]%' 
         AND col5 NOT LIKE 'thing209' 
         AND col5 NOT LIKE 'thing210');

原因是我有很多我在col5中处理的(凌乱的)电话号码,总的来说,在所有列上都有大量的清理工作要做。其中一些电话号码将使用文本输入代替,根据上下文,我可能希望保留它们或过滤掉它们(即,电话号码被输入为“企业名称”或“企业”,或“alskfjalsdkjf”,而不是“555-5555”或“555 5555”等)。如果数据满足AND条件的标准(主要是过滤掉col5 not like '%555-5555%'的变体),那么我需要通过OR条件进一步检查和过滤col5中的任何非数字字符。
没有错误消息-相反,查询需要很长时间才能完成,并且提供了比开始时更多的数据行,这与应该发生的情况相反。基于table1table2的结构,通过连接两个表可能会引入重复行,但是我所做的条件和子集设置的数量应该比原始行数少得多,即使在这里和那里有一些重复。
我不知道我的逻辑在哪里失败了,任何帮助都是感激的:)

smdncfj3

smdncfj31#

除了marc_s建议的正确的语法更正之外,这实际上运行得很好。2结果是我在AND条件中有几个条件语句不正确(即,逻辑上应该是!=的几个=和逻辑上应该是not like的几个like),但总体结构和逻辑是合理的-在几个测试数据库上重新运行,它工作得很完美。如果这让任何人头疼,我道歉:)

rhfm7lfc

rhfm7lfc2#

您的逻辑看起来相当混乱,即使它提供了正确的结果。为了使查询更具可读性,我将尝试以下操作:
1)如果允许您向现有方案添加一些列,则可以添加一些有意义的列,这些列可以在查询中重复使用。您的表可能如下所示:

create table table1 
(
    Id INT NOT NULL,
    col1 VARCHAR(64),
    col2 VARCHAR(64),
    col3 VARCHAR(64),
    col4 VARCHAR(64),
    col5 VARCHAR(64),

    Thing4Like AS (CASE WHEN col4 > '#' AND col5 NOT LIKE 'thing4' THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END) PERSISTED,
    Thing56 AS (CASE WHEN col5 != 'thing5' AND col5 NOT LIKE 'thing6' THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END) PERSISTED
    -- other columns may come here
)

这使您可以编写可读性更强的查询,甚至使查询更快,因为某些信息是预先计算的。
2)如果不能修改模式,可以在table1上创建一个视图,其中包含如上所述的额外逻辑。为了获得额外的性能,它们可以是indexed

相关问题