为什么SQL查询在使用多个OR条件时会返回其他行?

时间:2018-01-04 13:37:27

标签: sql

您好我的程序中有Filter选项。enter image description here

当我使用单个选项时,例如当我仅通过 STATUS = SCHEDULED 进行过滤时,我会得到正确的列表,如下所示 enter image description here

但是当我给出多个条件时,SQl查询返回更多与日期无关的额外行。像贝娄一样

enter image description here

我正在尝试使用 STATUS = SCHEDULED CUSTOMER ID = 87 过滤订单。

我参考了here1 here2

而bellow是我的SQL查询

SELECT
    *
FROM
    workforce_customerorder
WHERE
    ORDER_ID LIKE '$sOrder'
UNION
SELECT
    *
FROM
    workforce_customerorder
WHERE
    CUSTOMER_ID LIKE '%$sCustomerID%'
UNION
SELECT
    *
FROM
    workforce_customerorder
WHERE
    AGENT_NUMBER LIKE '%$sAgentNumber%'
UNION
SELECT
    *
FROM
    workforce_customerorder
WHERE
STATUS LIKE
    '$sStatus'
UNION
SELECT
    *
FROM
    workforce_customerorder
WHERE
    GST_NUMBER LIKE '$sGST'
UNION
SELECT
    *
FROM
    workforce_customerorder
WHERE
    DATE(ORDER_DATE) BETWEEN '$sOrderDateFrom' AND '$sOrderDateTo'

我需要最好的SQl查询。提前致谢

好我尝试使用AND后,我得到了

enter image description here

6 个答案:

答案 0 :(得分:2)

您应该只有一个查询,其中WHERE子句仅对已设置的列执行过滤

SELECT *
FROM workforce_customerorder
WHERE
    (ORDER_ID = COALESCE('$sOrder', ORDER_ID)) AND
    (CUSTOMER_ID LIKE '%$sCustomerID%' OR '$sCustomerID' IS NULL) AND
    (AGENT_NUMBER LIKE '%$sAgentNumber%' OR '$sAgentNumber' IS NULL) AND
    (STATUS = COALESCE('$sStatus', STATUS)) AND
    (GST_NUMBER = COALESCE('$sGST', GST_NUMBER)) AND
    (DATE(ORDER_DATE) BETWEEN COALESCE('$sOrderDateFrom', ORDER_DATE) AND COALESCE('$sOrderDateTo', ORDER_DATE))

请注意,没有通配符的LIKE等同于=。我发现指定哪些是完全匹配以及哪些是具有不同语法的子匹配更清楚。

答案 1 :(得分:0)

不要使用UNION。您应该在单个AND子句中使用WHERE

答案 2 :(得分:0)

您正在见证的这种行为是由于使用UNION,忽略UNION并使用AND之类的:

SELECT  * FROM  workforce_customerorder
WHERE
    ORDER_ID LIKE '$sOrder'
AND
    CUSTOMER_ID LIKE '%$sCustomerID%'
AND
    AGENT_NUMBER LIKE '%$sAgentNumber%'
....

使用UNION时虽然其中一个子集可能为空,但您可以从所有其他非空子集中获得结果

答案 3 :(得分:0)

如果你正在做一个UNION,意味着给我任何一套这两套,或两者兼而有之。如果你想要两个+条件为真,请尝试使用AND

答案 4 :(得分:0)

使用UNION合并列。由于您在联合中使用相同的数据表,因此您可以多次使用相同的列。您应该在AND语句中使用WHERE。以下是更正的查询。

SELECT *
FROM workforce_customerorder
WHERE
    ORDER_ID LIKE '$sOrder'
        AND CUSTOMER_ID LIKE '%$sCustomerID%'
        AND AGENT_NUMBER LIKE '%$sAgentNumber%'
        AND STATUS LIKE '$sStatus'
        AND GST_NUMBER LIKE '$sGST'
        AND DATE(ORDER_DATE) BETWEEN '$sOrderDateFrom' AND '$sOrderDateTo'

答案 5 :(得分:0)

好吧最后我找到了解决方案

     $query_order_id  = ($sOrder  != "") ? " AND (ORDER_ID LIKE '$sOrder') " : "";
    $query_customer_id = ($sCustomerID  != "") ? " AND (CUSTOMER_ID LIKE '%".$sCustomerID."' OR '".$sCustomerID."' IS NULL) " : "";
    $query_sAgentNumber =   ($sAgentNumber  != "") ? " AND (AGENT_NUMBER LIKE '%".$sAgentNumber."%' OR '".$sAgentNumber."' IS NULL) " : "";
    $query_sStatus =   ($sStatus  != "") ? " AND (STATUS LIKE '%".$sStatus."%' OR '".$sStatus."' IS NULL) " : "";
    $query_sGST =   ($sGST  != "") ? " AND (GST_NUMBER LIKE '%".$sGST."%' OR '".$sGST."' IS NULL) " : "";
    $query_sOrderDateFrom = ($sOrderDateFrom != "") ? " AND (DATE(ORDER_DATE) BETWEEN COALESCE('$sOrderDateFrom', ORDER_DATE) AND COALESCE('$sOrderDateTo', ORDER_DATE)) " : "";
//sql query here

    $sql = "SELECT * FROM workforce_customerorder where ORDER_ID IS NOT NULL".$query_order_id.$query_customer_id.$query_sAgentNumber.$query_sStatus.$query_sGST.$query_sOrderDateFrom;
    }

它与@Caleth显示的相同,但完全匹配的是通过在将变量传递给SQL查询之前应用三元运算符。谢谢你回答的每个人......