0

我有下面的查询,它似乎有效,但真的感觉我应该能够以更简单的方式完成它。基本上我有一个订单表和一个生产工作表。我想找到所有不完整的订单,这意味着在 production_work 表中没有订单条目,或者有条目并且工作总和等于订单要求的内容。

SELECT q.* FROM (
    SELECT o.ident, c."name" AS cname, s."name" as sname, o.number, o.created, o.due, o.name, o.ud, o.dp, o.swrv, o.sh, o.jmsw, o.sw, o.prrv, o.mhsw, o.bmsw, o.mp, o.pr, o.st
    FROM orders o
    INNER JOIN stations s on s.ident = o.station_id
    INNER JOIN clients c ON s.client_id = c.ident
    INNER JOIN (
        SELECT p.order_id, SUM(p.ud) AS ud, SUM(p.dp) AS dp, SUM(p.swrv) AS swrv, SUM(p.sh) AS sh, SUM(p.jmsw) AS jmsw, SUM(p.sw) AS sw, SUM(p.prrv) AS prrv,
            SUM(p.mhsw) AS mhsw, SUM(p.bmsw) AS bmsw, SUM(p.mp) AS mp, SUM(p.pr) AS pr, SUM(p.st) AS st
        FROM production_work p
        GROUP BY p.order_id
    ) pw ON o.ident = pw.order_id
    WHERE o.ud <> pw.ud OR o.dp <> pw.dp OR o.swrv <> pw.swrv OR o.sh <> pw.sh OR o.jmsw <> pw.jmsw OR o.sw <> pw.sw OR o.prrv <> pw.prrv OR
            o.mhsw <> pw.mhsw OR o.bmsw <> pw.bmsw OR o.mp <> pw.mp OR o.pr <> pw.pr OR o.st <> pw.st

    UNION

    SELECT o.ident, c."name" AS cname, s."name" as sname, o.number, o.created, o.due, o.name, o.ud, o.dp, o.swrv, o.sh, o.jmsw, o.sw, o.prrv, o.mhsw, o.bmsw, o.mp, o.pr, o.st
    FROM orders o
    INNER JOIN stations s on s.ident = o.station_id
    INNER JOIN clients c ON s.client_id = c.ident
    WHERE NOT EXISTS (
        SELECT 1 FROM production_work p WHERE p.ident = o.ident
    )
) q ORDER BY due DESC
4

3 回答 3

1

这是我最终得到的查询:

WITH work_totals AS (
    SELECT p.order_id, SUM(p.ud + p.dp + p.swrv + p.sh + p.jmsw + p.sw + p.prrv + p.mhsw + p.bmsw + p.mp + p.pr + p.st) AS total
    FROM production_work p
    GROUP BY p.order_id
), order_totals AS (
    SELECT ident, SUM(ud + dp + swrv + sh + jmsw + sw + prrv + mhsw + bmsw + mp + pr + st) AS total
    FROM orders
    GROUP BY ident
) 
SELECT o.ident, c."name" AS cname, s."name" as sname, o.number, o.created, o.due, o.name,      o.ud, o.dp, o.swrv, o.sh, o.jmsw, o.sw, o.prrv, o.mhsw, o.bmsw, o.mp, o.pr, o.st
FROM orders o
INNER JOIN stations s on s.ident = o.station_id
INNER JOIN clients c ON s.client_id = c.ident
INNER JOIN order_totals ot ON o.ident = ot.ident
LEFT OUTER JOIN work_totals w ON o.ident = w.order_id
WHERE w.order_id IS NULL OR ot.total <> w.total
于 2013-08-08T21:56:28.023 回答
0

这种形式的查询:显示在另一个表中没有匹配的行。

可以这样做:

select <columns>
from <table1>
left outer join <table2> on <join_condition>
where table2.column IS NULL

这将从 table1 中找到 table2 中没有任何匹配连接条件的行。

对于您的求和查询,我会做这样的事情......

select table1.order_number, total = sum(table2.order_amount)
from table1
left outer join table2 on table1.order_number = table2.order_number
group by order_number
having total < (some_number) OR total is null

这结合了获取不匹配的订单,以及获取少于某个总 order_amount 的订单。

于 2013-08-08T20:49:27.433 回答
0

UNION 中的两个查询几乎相同,因此您可以将它们合并为一个查询,如下所示。我只是将 JOIN 更改为 pw 子查询,使其成为 OUTER LEFT JOIN - 它与您的联合具有相同的结果,因为我在 WHERE 语句中包含了一个额外的 OR 子句来返回这些在 pw 子查询中没有记录的订单.

SELECT o.ident, c."name" AS cname, s."name" as sname, o.number, o.created, o.due, o.name, o.ud, o.dp, o.swrv, o.sh, o.jmsw, o.sw, o.prrv, o.mhsw, o.bmsw, o.mp, o.pr, o.st
FROM orders o
INNER JOIN stations s on s.ident = o.station_id
INNER JOIN clients c ON s.client_id = c.ident
LEFT OUTER JOIN (
    SELECT p.order_id, SUM(p.ud) AS ud, SUM(p.dp) AS dp, SUM(p.swrv) AS swrv, SUM(p.sh) AS sh, SUM(p.jmsw) AS jmsw, SUM(p.sw) AS sw, SUM(p.prrv) AS prrv,
        SUM(p.mhsw) AS mhsw, SUM(p.bmsw) AS bmsw, SUM(p.mp) AS mp, SUM(p.pr) AS pr, SUM(p.st) AS st
    FROM production_work p
    GROUP BY p.order_id
) pw ON o.ident = pw.order_id
WHERE (o.ud <> pw.ud OR o.dp <> pw.dp OR o.swrv <> pw.swrv OR o.sh <> pw.sh OR o.jmsw <> pw.jmsw OR o.sw <> pw.sw OR o.prrv <> pw.prrv OR
        o.mhsw <> pw.mhsw OR o.bmsw <> pw.bmsw OR o.mp <> pw.mp OR o.pr <> pw.pr OR o.st <> pw.st
       )
OR  pw.order_id IS NULL
ORDER BY due DESC
于 2013-08-08T20:49:44.770 回答