Question

I have three tables that I need to combine based on a certain criteria borrowed from each table. However, I keep running into an issue with data being omitted that I don't want to be that seems to be with how I am writing the WHERE statement. Here is a simplified example as the actual data I am working with is thousands of lines. Hopefully it doesn't cause confusion,

Table1

+-------+-----------+-----+-----+-----+-----+
|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   |
+-------+-----------+-----+-----+-----+-----+

Table2

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

Table3

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

So what I want to see is the items on Table1 that have no 'LB' in either Table1 or Table2 in PACK2 or PACK3 and have inventory from Table3. (I want to see all the items we have inventory of that don't have weights since it affects how trucks are loaded). The point of Table2 is that if Table1 has a value under Class, it should pull the info from Table2. Otherwise, it should just use the info from Table1. (Don't ask me why it was designed this way). I want the info from Table2 in the columns next to the info from Table1, and do some junk in Excel to move info if Class is not blank, but never mind that for now.

This is the query I have written:

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;

So I expect to end up with a table that looks like:

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

However, what I end up with is just the second line. It is only showing the items that have a value under Class.

After messing with many parts of the query, it seems to be the WHERE statement. If I change it to:

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

This results in items showing up with and without value under Class--which I want--but then it still shows items under t2.PACK2 AND t2.PACK3 that = 'LB'--which I don't want.

Any suggestions?

Was it helpful?

Solution

In your query, the values from t2 and t3 can be NULL. These automatially fail the where clause.

The solution is to move these conditions into the on clause:

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;

EDIT:

This is a complicated condition. I think you want a left outer join. Then you want to check if the join fails or that a match is not to 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;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top