使用多个like条件的选择查询

3
以下是一份现有的 MS SQL Server 2008 报告查询。
SELECT
    number, batchtype, customer, systemmonth, systemyear, entered, comment, totalpaid
FROM
    payhistory LEFT OUTER JOIN agency ON
        payhistory.SendingID = agency.agencyid      
WHERE
    payhistory.batchtype LIKE 'p%' AND
    payhistory.entered >= '2011-08-01 00:00:00.00' AND
    payhistory.entered <  '2011-08-15 00:00:00.00' AND
    payhistory.systemmonth = 8 AND
    payhistory.systemyear = 2011 AND
    payhistory.comment NOT LIKE 'Elit%'

结果将如下所示:
number  batchtype   customer    systemmonth systemyear  entered     comment         totalpaid
6255756 PC      EMC1106     8       2011        12:00:00 AM DP From - NO CASH       33
5575317 PA      ERS002      8       2011        12:00:00 AM MO-0051381526 7/31      20
6227031 PA      FTS1104     8       2011        12:00:00 AM MO-10422682168 7/30     25
6232589 PC      FTS1104     8       2011        12:00:00 AM DP From - NO CASH       103
2548281 PC      WAP1001     8       2011        12:00:00 AM NCO DP $1,445.41        89.41
4544785 PCR     WAP1001     8       2011        12:00:00 AM NCO DP $1,445.41        39

我想要做的是修改查询,以排除顾客名称类似于“FTS%”和“EMC%”,以及批次类型为“PC”的记录。如您在结果集中看到的,有些记录的顾客名称类似于“FTS%”,但批次类型为“PA”。我希望保留这些记录在结果中。感谢您提供任何想法。


2
你得到了哪些不期望的结果? - CamelSlack
那么,为什么你说“只有当btype ='PC'”然后又放了btype <> 'PC' - Lamak
你的SQL语句多了一个括号,或者缺少一个。 - Matthew
5个回答

4
你的查询包含大小写混合的字符串比较目标。据我所知,SQL Server默认情况下不区分大小写;这可能是导致你的查询出现问题的原因吗?请检查this answer中的排序规则。
编辑:根据你更新后的问题,你不能只使用一个AND子句并在前面加上NOT吗?换句话说,添加一个“AND not(x)”子句,其中“x”是定义要排除的记录的条件?由于它是一个OR,所以你需要嵌套客户测试。 例如:
... payhistory.comment NOT LIKE 'Elit%'
AND not ((customer like 'FTS%' or customer like 'EMC%') AND batchtype = 'PC')

作为一则附注,我认为在某些情况下(但并非全部情况),LIKE子句可能会导致低效的表扫描。因此,如果这个查询将被用于性能敏感的角色,请检查查询计划,并优化表以适应。

是的!那正是我需要做的。我花了太多时间试图组合那个语句,却不知道我可以使用“NOT”参数来过滤掉那些记录。感谢大家! - user992322
太好了!此外,如果它回答了你的问题,你可以将其标记为答案吗? - Geoff

3
$sql="select * from builder_property where builder_pro_name LIKE '%%' OR builder_pro_name LIKE '%za%' AND status='Active'";

这将返回表格中所有以 plazacomplex 结尾的建造者属性名称。

0

可能是因为你的服务器区分大小写。在这种情况下,下面的查询将起作用。

SELECT
table1.number, table1.btype, table1.cust, table1.comment, table2.ACode
FROM
table1 LEFT OUTER JOIN table2 ON table1.1ID = table2.2ID
WHERE
lower(table1.btype) LIKE 'p%' AND
lower(table1.comment) NOT LIKE 'yyy%' AND
lower(table1.cust) NOT LIKE 'abc%' AND
lower(table1.cust) NOT LIKE 'xyz%' AND
lower(table1.btype) <> 'pc'

0
将此条件添加到WHERE子句中:
NOT((customer LIKE 'FTS%' OR customer LIKE 'EMC%') AND batchtype='PC')

假设您的其他结果都是正常的,您只想过滤掉它们,那么整个查询将是:

SELECT
    number, batchtype, customer, systemmonth, systemyear, entered, comment, totalpaid
FROM
    payhistory 
    LEFT OUTER JOIN agency ON
        payhistory.SendingID = agency.agencyid      
WHERE
    payhistory.batchtype LIKE 'p%' AND
    payhistory.entered >= '2011-08-01 00:00:00.00' AND
    payhistory.entered <  '2011-08-15 00:00:00.00' AND
    payhistory.systemmonth = 8 AND
    payhistory.systemyear = 2011 AND
    payhistory.comment NOT LIKE 'Elit%' AND
    NOT((payhistory.customer LIKE 'FTS%' OR payhistory.customer LIKE 'EMC%') AND payhistory.batchtype='PC')

希望这对你有用。

0

在构建复杂的where子句时,使用括号来保持一切清晰是一个好主意。此外,在使用多个NOT LIKE语句时,您必须使用ORs将所有NOT LIKE条件组合在一起,并将它们包装在单独的AND条件中,如下所示...


WHERE     
    (payhistory.batchtype LIKE 'p%')
AND (payhistory.entered >= '2011-08-01 00:00:00.00')
AND (payhistory.entered <  '2011-08-15 00:00:00.00')
AND (payhistory.systemmonth = 8 )
AND (payhistory.systemyear = 2011)
AND ( // BEGIN NOT LIKE CODE

    (payhistory.comment NOT LIKE 'Elit%') 

OR  (
    (payhistory.customer NOT LIKE 'EMC%') AND 
    (payhistory.batchtype = 'PC')
    ) 

OR  (
    (payhistory.customer NOT LIKE 'FTS%') AND 
    (payhistory.batchtype = 'PC')
    )

    ) //END NOT LIKE CODE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接