目前,您的查询中有大量重复的代码,我在此重复这些代码,布局更加系统,并标记为重复:
(SELECT *
FROM bills INNER JOIN cats INNER JOIN suppliers -- ER1A
INNER JOIN new_cards
WHERE new_cards.`Card_Code` LIKE '%8%' -- NR1A
AND bills.`Sup_ID` = suppliers.`Sup_ID` -- ER2A
AND new_cards.`Sup_ID` = suppliers.`Sup_ID` -- NR2A
AND cats.`Cat_ID` = bills.`Cat_ID` -- ER3A
AND new_cards.`Cat_ID` = cats.`Cat_ID` -- NR3A
AND new_cards.`Bill_ID` = bills.`Bill_ID`) -- NR4A
UNION
(SELECT *
FROM bills INNER JOIN cats INNER JOIN suppliers -- ER1B
INNER JOIN sold_cards
WHERE sold_cards.`Card_Code` LIKE '%8%' -- NR1B
AND bills.`Sup_ID` = suppliers.`Sup_ID` -- ER2B
AND sold_cards.`Sup_ID` = suppliers.`Sup_ID` -- NR2B
AND cats.`Cat_ID` = bills.`Cat_ID` -- ER3B
AND sold_cards.`Cat_ID` = cats.`Cat_ID` -- NR3B
AND sold_cards.`Bill_ID` = bills.`Bill_ID`) -- NR4B
ERxx 标签表示“完全重复”,NRxx 标签表示“接近重复”。我会在最少的数据量上构建 UNION,并在连接中使用 ON 条件,如下所示:
SELECT *
FROM bills
INNER JOIN cats ON bills.`Cat_ID` = cats.`Cat_ID`
INNER JOIN suppliers ON bills.`Sup_ID` = suppliers.`Sup_ID`
INNER JOIN
(SELECT * FROM new_cards
UNION
SELECT * FROM sold_cards
) AS cards ON cards.`Bill_ID` = bills.`Bill_ID`
WHERE cards.`Card_Code` LIKE '%8%'
AND cards.`Sup_ID` = suppliers.`Sup_ID`
AND cards.`Cat_ID` = cats.`Cat_ID`
WHERE 子句中的最后两个条件也是连接条件;可以将它们上移到 ON 子句中。但是,它们也应该是多余的——或者,如果它们不是多余的,它们很可能是您遇到问题的原因。
这种重新表述的一个优点是,您可以通过简单地执行 UNION 子查询来演示它返回的内容。您可能更愿意将 Card_Code 上的过滤器放入 UNION;这样,您会看到(可能)更少的数据行。这可以永久完成;您可能最终在最外层的查询中没有 WHERE 子句。
您还应该通过单独运行 UNION 的后半部分来测试您的原始查询,以查看它返回的内容。如果按照您的建议,它什么都不返回,那么您可以单独调试查询的后半部分。例如,问你一个问题:新卡有有效的账单代码吗?
如果没有表的(最少)样本数据,就不可能再做任何事情了——比如new_cards 和sold_cards 各有 3 或 4 行(每行中的一行与 Card_Code 上的过滤条件不匹配),然后是 bills、cats 和 suppliers 表中必要的支持行(其中任何一个都不应超过 8 行)。
您应该只在每个表中显示最少的必要列,再加上最多一个额外的列。例如,bills 具有列 Sup_ID 和 Bill_ID;您应该显示这些值,也许还有另一个('Bill_Name' 或其他),尽管另一个并不是真正必要的。它还有助于显示标识主键和外键的最小模式。您似乎有一组非常相互关联的表格。
您应该显示您从查询中获得的输出和您期望的输出,并根据您的示例数据解释为什么两者不同。