2

私は2つのテーブルを持っています:

  • PERSONperson_idtotal
  • DATAdata_a、、、、およびdata_b_data_cdata_person_id

DATA各「人」は、標準の1対多の関係に0個以上のエントリを持つことができます。PERSONの値の合計であるtotal列がありますDATAtotal現在、と実際のエントリの間には、正しいが間違っているDATA場所にいくつかの不一致があります。DATAtotal

これは、不一致を見つけるために使用しているクエリです。

SELECT
  person_id
FROM PERSON JOIN (
  SELECT
    data_person_id,
    SUM( data_a + data_b + data_c ) as data_total
  FROM
    DATA
  GROUP BY
    data_person_id
  ) x ON data_person_id = person_id
WHERE
  person_total != data_total

バックエンドがPostgres9.xになるクエリとして、Hibernateを介してこれを行う予定です。

私が理解/修正しようとしている間違ったクエリは次のとおりです。

UPDATE
  ONLY PERSON
SET
  total = data_info.calc_total
FROM (
  SELECT
    SUM( data_a + data_b + data_c ) as calc_total
  FROM
    DATA
  WHERE
    DATA.data_person_id = person_id
  GROUP BY
    DATA.data_person_id
) as data_info
WHERE
  PERSON.person_id IN (
    SELECT
      data_person_id
    FROM PERSON JOIN (
      SELECT
        data_person_id,
        SUM( data_a + data_b + data_c ) as data_total
      FROM
        DATA
      GROUP BY
        data_person_id
      ) x ON person_id = data_person_id
    WHERE
      total != data_total
  )

現在、が原因で実行されませんWHERE DATA.data_person_id = person_id。しかし、それを取り除くと、間違った値が使用されます。

以下はうまくいくようですが、私は理由について混乱しています:

UPDATE
  ONLY PERSON
SET
  total = data_info.calc_total
FROM 
  PERSON P JOIN (
    SELECT
      data_person_id,
      SUM( data_a + data_b + data_c ) as calc_total
    FROM
      DATA
    WHERE
      DATA.data_person_id = person_id
    GROUP BY
      DATA.data_person_id
  ) as data_info ON P.person_id = data_person_id
WHERE
  PERSON.person_id IN (
    SELECT
      data_person_id
    FROM PERSON JOIN (
      SELECT
        data_person_id,
        SUM( data_a + data_b + data_c ) as data_total
      FROM
        DATA
      GROUP BY
        data_person_id
      ) x ON person_id = data_person_id
    WHERE
      total != data_total
  )

私の問題は、ドキュメントの誤解にあると思います(自己結合に関する部分を推測しています)。

また、このクエリを改善する方法はありがたいです!

4

2 に答える 2

2

これは通常の構文UPDATE...FROMです。したがって、WHERE以外の最後のクエリを使用します

UPDATE
  ONLY PERSON
SET
  total = data_info.calc_total
FROM 
  PERSON P JOIN (
    SELECT
      data_person_id,
      SUM( data_a + data_b + data_c ) as calc_total
    FROM
      DATA
    WHERE
      DATA.data_person_id = person_id
    GROUP BY
      DATA.data_person_id
  ) as data_info ON P.person_id = data_person_id
于 2012-10-11T00:24:31.240 に答える
2

あなたのクエリは複雑になる方法のようです。タスクは次のように単純にする必要があります。

UPDATE person p
SET    total = d.calc_total
FROM (
  SELECT data_person_id, sum(data_a + data_b + data_c) as calc_total
  FROM   data
  GROUP  BY 1
) d
WHERE  p.person_id = d.data_person_id
AND    p.total IS DISTINCT FROM d.calc_total;
  • によってグループ化された、テーブルcalc_totalからの最初の集計。datadata_person_id

  • 次に、このサブクエリをのFROM句で使用しUPDATEます。

  • NULL値がカバーされていることを確認するために使用IS DISTINCT FROMしますが、実際には変更される行のみが更新されます。
    関連するすべての列が定義されているNOT NULL場合は、代わりに使用できます=

->sqlfiddleデモ。

于 2012-10-11T00:44:47.757 に答える