Java 更新子查询中的数据

Java 更新子查询中的数据,java,sql,hibernate,postgresql,Java,Sql,Hibernate,Postgresql,我有两张桌子: PERSON带有列PERSON\u id和total 数据带有列数据a、数据b、数据c和数据个人id 每个“人”在数据中可以有零个或多个条目——您的标准一对多关系PERSON有一个total列,该列是数据中的值之和。目前,total与DATA中的实际条目之间存在一些差异,DATA是正确的,但total是错误的 这是我用来查找差异的查询: SELECT person_id FROM PERSON JOIN ( SELECT data_person_id,

我有两张桌子:

  • PERSON
    带有列
    PERSON\u id
    total
  • 数据
    带有列
    数据a
    数据b
    数据c
    数据个人id
每个“人”在
数据中可以有零个或多个条目
——您的标准一对多关系
PERSON
有一个
total
列,该列是
数据中的值之和。目前,
total
DATA
中的实际条目之间存在一些差异,
DATA
是正确的,但
total
是错误的

这是我用来查找差异的查询:

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
我计划通过Hibernate来实现这一点,作为一个查询,后端将是Postgres9.x

我试图理解/修复的错误查询是:

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\u person\u id=person\u 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
  )
我相信我的问题在于我对的误解(我猜是关于自连接的部分)


此外,任何改进此查询的方法都将不胜感激

这是普通语法
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

这是从
更新的普通语法。 所以,除了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

看来你的问题太复杂了。任务应简单到:

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;
  • 数据
    表中首先聚合
    计算总计
    ,按
    数据(人员id)
    分组

  • 然后在
    UPDATE
    的FROM子句中使用此子查询

  • 我使用
    不同,以确保覆盖空值,而实际上只更新可能更改的行。
    如果所有涉及的列都定义为
    非空
    ,则可以改用
    =


看来您的查询太复杂了。任务应简单到:

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;
  • 数据
    表中首先聚合
    计算总计
    ,按
    数据(人员id)
    分组

  • 然后在
    UPDATE
    的FROM子句中使用此子查询

  • 我使用
    不同,以确保覆盖空值,而实际上只更新可能更改的行。
    如果所有涉及的列都定义为
    非空
    ,则可以改用
    =


如果我不使用WHERE,那么
PERSON
中的所有条目不都会被更新吗?为什么?您需要创建内部联接表,因此total列对应于每个与data\u person\u id匹配的person\u id的calc\u total列。@nevets1219:此查询根本不起作用。您不能在子查询中引用
person\u id
。测试运行按预期生成:
错误:FROM中的子查询不能引用相同查询级别的其他关系
如果我不使用WHERE,那么
PERSON
中的所有条目不都会被更新,不管其正确性如何吗?为什么?您需要创建内部联接表,因此total列对应于每个与data\u person\u id匹配的person\u id的calc\u total列。@nevets1219:此查询根本不起作用。您不能在子查询中引用
person\u id
。测试运行按预期生成:
错误:FROM中的子查询不能引用相同查询级别的其他关系
感谢您对每个部分的解释。另外,SQLFiddle非常方便!谢谢你解释每一部分。另外,SQLFiddle非常方便!