重写mysql查询返回意外结果,试图找出原因

时间:2010-03-26 16:14:58

标签: mysql

前一段时间我匆忙创建了一个混乱的查询,以获取产品代码列表。我现在正在尝试清理我的表和代码。我最近尝试重写查询,以便更容易使用和理解。原始查询效果很好,但它需要多个搜索字符串才能进行一次搜索,因为它使用UNIONS,并且还有一些其他问题。我新修改的查询更容易理解,只需要一个搜索字符串,但返回的结果不同。基本上新的查询是留下记录,我想了解为什么,以及如何解决它。以下是两个查询(搜索字符串都为空):

原始查询:

$query = 'SELECT product_code FROM bus_warehouse_lots WHERE status=\'2\''.$search_string_1
    .' UNION SELECT product_code FROM bus_po WHERE status=\'0\''.$search_string_2
    .' UNION SELECT bus_warehouse_entries.new_product_code AS product_code FROM (bus_warehouse_entries LEFT JOIN bus_warehouse_transfers ON bus_warehouse_entries.picking_ticket_num=bus_warehouse_transfers.pt_number) LEFT JOIN bus_warehouse_lots ON bus_warehouse_entries.ebooks_lot_id=bus_warehouse_lots.id WHERE bus_warehouse_entries.type=\'6\' AND bus_warehouse_transfers.status=\'0\''.$search_string_3
    .' UNION SELECT bus_contracts.main_product AS product_code FROM bus_contracts LEFT JOIN bus_warehouse_lots ON bus_contracts.main_product=bus_warehouse_lots.product_code WHERE bus_contracts.status=\'0\''.$search_string_4
    .' UNION SELECT prod_id AS product_code FROM bus_products WHERE last_usage > \''.date('Y-m-d', strtotime('-12 months')).'\''.$search_string_5
    .' ORDER BY product_code';

新查询:

$query = 'SELECT bus_products.prod_id FROM bus_products'
    .' LEFT JOIN (bus_warehouse_lots, bus_po, bus_warehouse_entries, bus_contracts) ON ('
    .'bus_products.prod_id = bus_warehouse_lots.product_code'
    .' AND bus_products.prod_id = bus_po.product_code'
    .' AND bus_products.prod_id = bus_warehouse_entries.new_product_code'
    .' AND bus_products.prod_id = bus_contracts.main_product)'
    .' LEFT JOIN bus_warehouse_transfers ON'
    .' bus_warehouse_entries.picking_ticket_num = bus_warehouse_transfers.pt_number'
    .' WHERE (bus_products.last_usage > \''.date('Y-m-d', strtotime('-12 months')).'\''
    .' OR bus_warehouse_lots.status = \'2\''
    .' OR bus_po.status = \'0\''
    .' OR (bus_warehouse_entries.type = \'6\' AND bus_warehouse_transfers.status = \'0\')'
    .' OR bus_contracts.status = \'0\')'
    .$search_string_6
    .' GROUP BY bus_products.prod_id'
    .' ORDER BY bus_products.prod_id';

2 个答案:

答案 0 :(得分:0)

虽然我不知道你的代码语言,但看起来像PHP,请原谅我缺少。$ string格式化。我知道你使用转义序列作为静态值周围的引号,例如状态,类型等,我为了简单的可读性而剥离了。

当我知道我将加入表并期望双方的条目(因此LEFT JOIN)时,我跳过它并将其作为我的直接WHERE子句并直接在FROM中列出所有表。另外,对于MySQL的性能,我告诉它按照我所说的顺序进行查询(通过关键字STRAIGHT_JOIN)

SELECT STRAIGHT_JOIN
        DISTINCT bus_products.prod_id 
    FROM
        bus_products,
        bus_warehouse_lots, 
        bus_po, 
        bus_warehouse_entries, 
        bus_contracts,
        bus_warehouse_transfers
    WHERE 
            bus_products.prod_id = bus_warehouse_lots.product_code
        AND bus_products.prod_id = bus_po.product_code
        AND bus_products.prod_id = bus_warehouse_entries.new_product_code
        AND bus_products.prod_id = bus_contracts.main_product
        AND bus_warehouse_entries.picking_ticket_num = bus_warehouse_transfers.pt_number
        AND (       bus_products.last_usage > {yourDateStringFormatted}
                OR  bus_warehouse_lots.status = '2' 
                OR  bus_po.status = '0'
                OR (    bus_warehouse_entries.type = '6' 
                    AND bus_warehouse_transfers.status = '0')
                OR bus_contracts.status = '0'
            ) 
            { plus your $search_string_6  }
     ORDER BY
           bus_products.prod_id

我会删除你的Last_Usage日期条款和你的搜索字符串6,以确保你至少得到“所有”预期条目。如果您还在外面,请确保您的OR / AND条件在预期的情况下正确平衡。然后,添加回你的日期限制,确保没问题,然后添加你的最终搜索字符串6。

答案 1 :(得分:0)

这是dq,不知道如何以我自己的身份重新登录。反正...

我看到你在使用AND来确定表关系时所说的内容,但这不会只返回符合所有AND条件的结果吗?如果没有匹配的转移记录,这不会返回产品ID吗?有时,有些产品ID可以在其中一列中找到匹配项,但在任何其他列中都没有匹配项。我希望查询能够在所提到的任何一个表中提取可以找到匹配产品ID的记录,但不能返回在任何其他表中找不到匹配表的记录。这仍然是最好的方式吗?