0

我正在尝试在“PROD_CD”上加入四个单独的查询,以将正确的输出返回到一个查询中,以防止之后必须将查询合并到另一种语言中。使用当前的(我已经尝试了很多变体,都有各种问题),我收到了很多重复的结果和不同数量的重复结果。

这是我一直在尝试的当前查询(所有日期函数都用于确定一段时间内的数据集 - 数据库非常旧并使用 Clarion 时间):

$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";

这是它输出的示例:

数组 ( [prod_id] => ALG-809
[total_so] => 4 [total_edi_so] => 46 [in_stock] => 0 ) 数组 ( [prod_id] => ALG-809
[total_so] => 6 [total_edi_so] => 46 [in_stock] => 0 ) 数组 ( [prod_id] => ALG-809
[total_so] => 7 [total_edi_so] => 46 [in_stock] => 0 )

以下是返回正确结果的四个单独的查询:

$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";

我确定这是我正在使用的 JOIN,但我一生都无法弄清楚。有什么建议么?谢谢!

4

2 回答 2

0

为什么不使用一个DISTINCT

$query_ats = "SELECT DISTINCT
            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";
于 2013-01-25T19:59:58.100 回答
0

在这种情况下,SQL 的规则 1:首先从您想要行的事物中选择,然后加入您想要更多信息的事物。在您的情况下,您想要的似乎是产品 ID,这似乎是唯一存储在inv_data表中的,所以我们将从它开始。

select
        i.prod_cd as product,
        i.descrip as description,
        i.in_stock
    from
        inv_data as i
    where
        i.class_cd = 'ALG7'
    order by
        i.prod_cd asc
;

你会得到一个,因为每个只存储一个。剩下的只是细节。让我们添加一些连接

select
        i.prod_cd as product,
        i.descrip as description,
        i.in_stock,
        sum(l.order_qty) as l_total_so,
        sum(e.order_qty) as e_total_so
    from
        inv_data as i
        inner join plog as p
            on i.prod_cd = p.prod_cd
        inner join ord_log as l
            on i.prod_cd = l.prod_cd
        inner join ediordlg as e
            on i.prod_cd = e.prod_cd
    where
        i.class_cd = 'ALG7'
    order by
        i.prod_cd asc
    group by
        i.prod_cd,
        i.descrip,
        i.in_stock
;

您不需要在on子句中列出这么多列,因为无论如何它们都是相同的(根据定义,因为较早的内部连接成功)。

如果事实证明plog不是inv_data您的主表,只需在查询中反转它们。如果您希望将两个总值放在一起,请使用sum(l.order_qty + e.order_qty) as total_so而不是创建两列。

要理解的是连接可以使结果成倍增加。了解哪些表有更多并在每种情况下做一些事情来限制每次额外的“额外”结果将导致一个干净的结果集。在这种情况下,可能只是求和和分组就足够了,但在复杂的情况下,您需要加入一个选择足够不同集合的子查询。

而且,在相关说明中,distinct您的查询是毒药!它有一个非常具体的目的,即修复“加入后重复的行太多”。如果你使用它,你可能有一个错误,它可能会产生未知的其他副作用。尝试先使用group by更智能的on语句修复它,然后再使用嵌套查询。

与您的问题无关,但很重要:您似乎正在扩展$x查询中的变量。这可能不安全(或有效);尝试改用参数化查询。

于 2013-01-25T21:38:25.357 回答