我根据来自new_cards表和old_cards表的卡号从2个表中获取数据 "如果card_code包含' 8'"
,我想从这两个表中显示card_code和card_status(SELECT *
FROM bills INNER JOIN cats INNER JOIN suppliers
INNER JOIN new_cards
WHERE new_cards.`Card_Code` LIKE '%8%'
AND bills.`Sup_ID` = suppliers.`Sup_ID`
AND new_cards.`Sup_ID` = suppliers.`Sup_ID`
AND cats.`Cat_ID` = bills.`Cat_ID`
AND new_cards.`Cat_ID` = cats.`Cat_ID`
AND new_cards.`Bill_ID` = bills.`Bill_ID`)
UNION
(SELECT * FROM bills INNER JOIN cats INNER JOIN suppliers
INNER JOIN sold_cards WHERE
sold_cards.`Card_Code` LIKE '%8%'
AND bills.`Sup_ID` = suppliers.`Sup_ID`
AND sold_cards.`Sup_ID` = suppliers.`Sup_ID`
AND cats.`Cat_ID` = bills.`Cat_ID`
AND sold_cards.`Cat_ID` = cats.`Cat_ID`
AND sold_cards.`Bill_ID` = bills.`Bill_ID`)
但结果是第一张表中的card_coldes只是new_cards
答案 0 :(得分:1)
你确定有匹配吗?删除第二个查询,看看是否返回任何结果。如果组合行与所有表中的所有条件都不匹配,则不会出现。这意味着必须有行连接new_cards和solid卡。您可能正在寻找LEFT JOIN而不是INNER JOIN
由于你没有在new_cards条件中提及solid_cards,反之亦然,它也会尝试加入与第二个条件相匹配的每一行,再乘以new_cards中的每一行。小心这样的OR查询,它们效率极低,尤其是在大型数据库上。
答案 1 :(得分:1)
提示:为避免查询结果中出现任何重复,每行的所有记录都不应具有不同的值。
如果它发生,那么你可以使用不同的功能。
答案 2 :(得分:1)
目前,您的查询中有大量重复的代码,我在此重复更详细地展示并标记以表示重复:
(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'或其他),尽管另一个并不是必需的。它还有助于显示识别主键和外键的最小模式。您似乎有一组非常相互关联的表格。
您应该显示从查询中得到的输出和您期望的输出,并根据您的样本数据解释两者的不同之处。