0

以下のクエリは機能しているように見えますが、もっと簡単な方法で実行できるはずだと本当に感じています。基本的に、orders テーブルと production_work テーブルがあります。完了していないすべての注文を見つけたいと考えています。つまり、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

これにより、結合条件に一致する table2 に何もない table1 の行が検索されます。

集計クエリの場合、次のようにします...

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_mount 未満の注文の取得を組み合わせたものです。

于 2013-08-08T20:49:27.433 に答える
0

UNION の 2 つのクエリはほとんど同じなので、次のように 1 つのクエリにマージできます。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 に答える