Vertica

时间:2017-08-10 11:32:15

标签: sql vertica

我想根据UPDATE表数据client维度表event中的某些列:

UPDATE client AS c
SET 
    some_attr_last_value = last_attr_values.value 
FROM (

  SELECT
    l.client_id,
    value,
    ROW_NUMBER() OVER (PARTITION BY l.client_id ORDER BY timestamp DESC) AS num
  FROM event AS l
  WHERE 
    timestamp > DATE_TRUNC('month', NOW() - INTERVAL '1 month')

) AS last_attr_values

WHERE 
    last_attr_values.num = 1 AND 
    c.client_id = last_attr_values.client_id AND 
    c.some_attr_last_value <> last_attr_values.value;

我已经有了一些像上面这样的查询:它们以相同的方式更新其他列(仅与其他列一起)并且运行良好。但是一个查询会产生错误:

  

错误6745:重复键值:'client_id = ...' - 违反约束'... .client.C_PRIMARY'

但我不会尝试更改client_id。为什么会出现这个错误?

我检查client表,但它没有重复。 ANALYZE_CONSTRAINTS('client')也不会返回任何违规行为。

版本是7.2.2-1。

1 个答案:

答案 0 :(得分:3)

问题不在于您的客户表,而是内部选择。

SELECT
    l.client_id,
    value,
    ROW_NUMBER() OVER (PARTITION BY l.client_id ORDER BY timestamp DESC) AS num
  FROM event AS l
  WHERE 
    timestamp > DATE_TRUNC('month', NOW() - INTERVAL '1 month')

SELECT中有什么可以确保每个客户端有一条记录?

假设您有多个客户有多个事件的事件。

  • Client_id 1 10:00
  • Client_id 1 10:05
  • Client_id 9 10:05
  • Client_id 9 10:06
  • Client_id 1 10:07

因为您的窗口函数按时间戳排序

ROW_NUMBER() OVER (PARTITION BY l.client_id ORDER BY timestamp DESC) AS num

你会得到

  • Client_id 1 1
  • Client_id 1 2
  • Client_id 9 1
  • Client_id 9 2
  • Client_id 1 1&lt; ----第二个Client_id 1,Row_number为1!

我认为您需要在ORDER BY中包含Client_id才能使查询生效。

更新:一段时间后,错误再次发生。我试图使用上面的解决方案,但不幸的是它没有帮助。仅使用临时表克服了错误:

CREATE LOCAL TEMPORARY TABLE last_values ON COMMIT PRESERVE ROWS 
AS SELECT client_id, value FROM (
  SELECT
    l.client_id,
    value,
    ROW_NUMBER() OVER (PARTITION BY l.client_id ORDER BY timestamp DESC) AS num
  FROM event AS l WHERE timestamp > DATE_TRUNC('month', NOW() - INTERVAL '1 month')
) last_values WHERE last_values.num = 1;

UPDATE client AS c 
SET some_attr_last_value = last_values.value
FROM last_values 
WHERE c.client_id = last_values.client_id AND c.some_attr_last_value <> last_attr_values.value

DROP TABLE last_values;

所以虽然问题解决了,但我没有找到确切的原因。