SQL查询在WHERE语句中加入3个表错误

时间:2014-01-16 03:50:29

标签: sql where

我需要根据从每个表中借用的某个条件来组合三个表。但是,我一直遇到一个问题,数据被省略,我不想这似乎与我如何编写WHERE语句。这是一个简化的例子,因为我正在使用的实际数据是数千行。希望它不会引起混淆,

表1

+-------+-----------+-----+-----+-----+-----+
|Item   |Description|Class|PACK1|PACK2|PACK3|
+-------+-----------+-----+-----+-----+-----+
|ACME123|Widget1    |ABC  |12   |LB   |EA   |
+-------+-----------+-----+-----+-----+-----+
|ACME456|Widget2    |DEF  |1    |LB   |EA   |
+-------+-----------+-----+-----+-----+-----+
|ACME789|Widget3    |     |20   |PC   |CT   |
+-------+-----------+-----+-----+-----+-----+
|ACME012|Widget4    |GHI  |     |     |     |
+-------+-----------+-----+-----+-----+-----+
|ACME034|WIdget5    |     |20   |PC   |CT   |
+-------+-----------+-----+-----+-----+-----+

表2

+-----+-----+-----+-----+
|Class|PACK1|PACK2|PACK3|
+-----+-----+-----+-----+
|ABC  |15   |LB   |EA   |
+-----+-----+-----+-----+
|DEF  |10   |LB   |EA   |
+-----+-----+-----+-----+
|GHI  |2    |SF   |PC   |
+-----+-----+-----+-----+

表3

+-------+--------+
|Item   |Quantity|
+-------+--------+
|ACME123|100     |
+-------+--------+
|ACME123|50      |
+-------+--------+
|ACME456|0       |
+-------+--------+
|ACME789|50      |
+-------+--------+
|ACME012|100     |
+-------+--------+
|ACME012|100     |
+-------+--------+
|ACME034|0       |
+-------+--------+

所以我想看到的是Table1上的项目在PACK2或PACK3中的Table1或Table2中没有'LB'并且具有表3中的库存。 (我希望看到我们库存的所有物品没有重量,因为它会影响卡车的装载方式)。表2的要点是,如果Table1的值在Class下,它应该从Table2中提取信息。否则,它应该只使用Table1中的信息。 (不要问我为什么这样设计)。我希望表1中的信息位于Table1的信息旁边的列中,如果Class不是空白,则在Excel中执行一些垃圾移动信息,但现在不用关注。

这是我写的查询:

SELECT t1.ITEM, t1.DESCRIPTION, t1.CLASS, t1.PACK1, t1.PACK2, t1.PACK3, t2.PACK1, t2. PACK2, t2.PACK3, SUM(t3.QUANTITY) as QOH
FROM Table1 t1
LEFT JOIN Table2 t2
  ON t1.CLASS = t2.CLASS
LEFT JOIN Table3 t3
  ON t1.ITEM = t3.ITEM
WHERE (t1.PACK2 != 'LB') AND (t1.PACK3 != 'LB') AND (t2.PACK2 != 'LB') AND (t2.PACK3 != 'LB')
GROUP BY t1.ITEM, t1.DESCRIPTION, t1.CLASS, t1.PACK1, t1.PACK2, t1.PACK3, t2.PACK1, t2. PACK2, t2.PACK3
ORDER BY t1.ITEM;

所以我希望最终得到一张表格如下:

+-------+-----------+-----+-----+-----+-----+------+------+------+---+
|ITEM   |Description|Class|PACK1|PACK2|PACK3|PACK11|PACK22|PACK33|QOH|
+-------+-----------+-----+-----+-----+-----+------+------+------+---+
|ACME789|Widget3    |     |20   |PC   |CT   |      |      |      |150|
+-------+-----------+-----+-----+-----+-----+------+------+------+---+
|ACME012|Widget4    |GHI  |     |     |     |2     |SF    |PC    |200|
+-------+-----------+-----+-----+-----+-----+------+------+------+---+

然而,我最终得到的只是第二行。它仅显示具有Class类下的值的项目。

在弄乱查询的许多部分之后,它似乎是WHERE语句。如果我将其更改为:

((t1.PACK2 != 'LB') AND (t1.PACK3 != 'LB')) OR ((t2.PACK2 != 'LB') AND (t2.PACK3 != 'LB'))

这导致项目在Class下显示有和没有值 - 我想要 - 但它仍然显示t2.PACK2和t2.PACK3下的项目='LB' - 我不想要。

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

在您的查询中,t2t3的值可以是NULL。这些会自动使where子句失败。

解决方案是将这些条件移到on子句中:

SELECT t1.ITEM, t1.DESCRIPTION, t1.CLASS, t1.PACK1, t1.PACK2, t1.PACK3,
       t2.PACK1, t2. PACK2, t2.PACK3, SUM(t3.QUANTITY) as QOH
FROM Table1 t1 LEFT JOIN
     Table2 t2
     ON t1.CLASS = t2.CLASS and t2.pack2 <> 'LB' and t2.pack3 <> 'LB' LEFT JOIN
     Table3 t3
     ON t1.ITEM = t3.ITEM
WHERE t1.PACK2 != 'LB') AND (t1.PACK3 != 'LB')
GROUP BY t1.ITEM, t1.DESCRIPTION, t1.CLASS, t1.PACK1, t1.PACK2, t1.PACK3, t2.PACK1, t2. PACK2, t2.PACK3
ORDER BY t1.ITEM;

编辑:

这是一个复杂的情况。我想你想要一个左外连接。然后,您想要检查连接是否失败是否匹配不是LB

SELECT t1.ITEM, t1.DESCRIPTION, t1.CLASS, t1.PACK1, t1.PACK2, t1.PACK3,
       t2.PACK1, t2. PACK2, t2.PACK3, SUM(t3.QUANTITY) as QOH
FROM Table1 t1 LEFT JOIN
     Table2 t2
     ON t1.CLASS = t2.CLASS LEFT JOIN
     Table3 t3
     ON t1.ITEM = t3.ITEM
WHERE (t1.PACK2 <> 'LB') AND (t1.PACK3 <> 'LB') AND
      (t2.PACK2 <> 'LB' or t2.PACK2 is null) AND (t2.PACK3 <> 'LB' or t2.PACK3 is NULL)
GROUP BY t1.ITEM, t1.DESCRIPTION, t1.CLASS, t1.PACK1, t1.PACK2, t1.PACK3,
         t2.PACK1, t2. PACK2, t2.PACK3
ORDER BY t1.ITEM;