I’m trying to join four separate queries on “PROD_CD” to return the correct output into one query to prevent having to merge the queries together in another language after. With the current one (and I’ve tried many variations, all with various problems), I’m receiving a lot of duplicate results and different numbers of duplicates for each.
Here’s the current query I’ve been trying (all the date functions are for determining dataset over a span of time – the database is very old and uses Clarion time):
$query_ats = "SELECT
plog.prod_cd as prod_id,
ord_log.ORDER_QTY as total_so,
ediordlg.ORDER_QTY as total_edi_so,
inv_data.IN_STOCK as in_stock
FROM plog
INNER JOIN ord_log
ON plog.prod_cd = ord_log.prod_cd
INNER JOIN ediordlg
ON plog.prod_cd = ediordlg.prod_cd AND ord_log.prod_cd = ediordlg.prod_cd
INNER JOIN inv_data
ON plog.prod_cd = inv_data.prod_cd AND ord_log.prod_cd = inv_data.prod_cd AND ediordlg.prod_cd = inv_data.prod_cd
WHERE
inv_data.CLASS_CD = 'ALG7'
AND
dateadd(day, plog.EST_DT, '18001228') BETWEEN getdate() and dateadd(day, $x, getdate())
AND
dateadd(day, ord_log.SHIP_DT, '18001228') BETWEEN getdate() and dateadd(day, $x, getdate())
AND
dateadd(day, ediordlg.SHIP_DT, '18001228') BETWEEN getdate() and dateadd(day, $x, getdate())
GROUP BY plog.prod_cd, plog.log_qty, ord_log.ORDER_QTY, ediordlg.ORDER_QTY, inv_data.IN_STOCK
ORDER BY plog.prod_cd ASC";
And this is a sample of what it outputs:
Array
(
[prod_id] => ALG-809
[total_so] => 4
[total_edi_so] => 46
[in_stock] => 0
)
Array
(
[prod_id] => ALG-809
[total_so] => 6
[total_edi_so] => 46
[in_stock] => 0
)
Array
(
[prod_id] => ALG-809
[total_so] => 7
[total_edi_so] => 46
[in_stock] => 0
)
Here are the four separate queries that return the correct results:
$query_stock = "SELECT
prod_cd,
inv_data.DESCRIP,
inv_data.IN_STOCK
from
inv_data
where
inv_data.CLASS_CD = 'ALG7'
ORDER BY
inv_data.prod_cd ASC";
$query_po = "SELECT
plog.prod_cd,
SUM(plog.log_qty) as total_po
FROM
plog JOIN inv_data ON plog.prod_cd = inv_data.prod_cd
WHERE
inv_data.CLASS_CD = 'ALG7'
AND
dateadd(day, EST_DT, '18001228') BETWEEN getdate() and dateadd(day, $x, getdate())
GROUP BY
plog.prod_cd
ORDER BY
plog.prod_cd ASC";
$query_so = "SELECT
ord_log.prod_cd,
SUM(ord_log.ORDER_QTY) as total_so
FROM
ord_log JOIN inv_data ON ord_log.prod_cd = inv_data.prod_cd
WHERE
inv_data.CLASS_CD = 'ALG7'
AND
dateadd(day, SHIP_DT, '18001228') BETWEEN getdate() and dateadd(day, $x, getdate())
GROUP BY
ord_log.PROD_CD
ORDER BY
ord_log.prod_cd ASC";
$query_edi = "SELECT
ediordlg.prod_cd,
SUM(ediordlg.ORDER_QTY) as total_so_EDI
FROM
ediordlg JOIN inv_data ON ediordlg.prod_cd = inv_data.prod_cd
WHERE
inv_data.CLASS_CD = 'ALG7'
AND
dateadd(day, SHIP_DT, '18001228') BETWEEN getdate() and dateadd(day, $x, getdate())
GROUP BY
ediordlg.PROD_CD
ORDER BY
ediordlg.prod_cd ASC";
I’m sure it’s the JOIN I’m using but I can’t figure it out for the life of me. Any suggestions? Thanks!
Rule 1 of SQL in cases like this: Select initially from the thing that you want rows out of, join to the things you want more information about. In your case what you want seems to be the product ID and this seems to be uniquely stored in the
inv_datatable, so we’ll start with that.You’ll get one of each because only one of each is stored. The rest is just details. Let’s add some joins
You don’t need to list so many columns in your
onclauses because they’re all the same anyway (by definition, because the earlier inner join succeeded).If it turns out that
plogand notinv_datais your master table simply reverse them in the query. If you want both total values together, usesum(l.order_qty + e.order_qty) as total_soinstead of creating two columns.The thing to understand is that joins can multiply the results. Understanding which tables have more and doing something in each case to limit the “extra” results each time they would be extra will result in a clean resultset. In this case probably just summing and grouping is enough, but in a complex case you would need to join to a sub-query that selects back a sufficiently distinct set.
And, on a related note,
distinctis poison for your query! It has a very specific purpose which is not to fix “too many duplicate rows after joining.” If you’re using it for that you probably have a bug that could have unknown other side effects. Try to fix it withgroup byand smarteronstatements first, then nested queries.Not related to your question, but important: It appears that you are expanding a variable
$xinside your query. This is probably not safe (or efficient); try to use a parametrized query instead.