使用子查询更新为所有记录设置相同的值

时间:2017-01-15 17:56:26

标签: postgresql postgresql-9.5

我试图根据列(updated_at)的值来计算每条记录的权重。当我运行以下查询时:

UPDATE buyers
SET weight = RankedRecords.rank / (RankedRecords.count + 1.0)
FROM (
  SELECT
    id,
    RANK() OVER (
      PARTITION BY board_list_id ORDER BY 'updated_at' ASC
      ) AS rank,
    COUNT(id) OVER (PARTITION BY board_list_id) AS count
  FROM buyers
) RankedRecords
WHERE buyers.id = RankedRecords.id

所有具有相同board_list_id的记录都会将其weight更新为相同的值。虽然我希望所有weight值都不同,并且取决于排名 仅运行子查询会产生正确的结果(每个记录具有不同的等级)。但更新并没有按预期工作 我应该改变什么?

1 个答案:

答案 0 :(得分:1)

您的查询中有一个非常微妙的错误。试试这个:

UPDATE 
    buyers
SET 
    weight = RankedRecords.rank / (RankedRecords.count + 1.0)
FROM 
(
    SELECT
        id,
        rank()    OVER (PARTITION BY board_list_id ORDER BY updated_at ASC) AS rank,
        count(id) OVER (PARTITION BY board_list_id) AS count
    FROM buyers
) RankedRecords
WHERE 
    buyers.id = RankedRecords.id ;

你的小错误:ORDER BY 'updated_at'只是ORDER BY 'constant-text'。如果要引用该列,可以使用"updated_at"(使用 double 引号)或updated_at(不使用它们,因为列的名称只是ASCII小写字符)。

试过:

CREATE TABLE buyers
(
    id integer not null primary key,
    board_list_id integer not null,
    updated_at timestamp not null default now(),
    weight double precision
) ;
INSERT INTO buyers (id, board_list_id, updated_at) 
VALUES 
    (1, 1, '2017-01-09'),
    (2, 1, '2017-01-10'),
    (3, 1, '2017-01-11'),
    (4, 1, '2017-01-12'),
    (5, 2, '2017-01-09'),
    (6, 2, '2017-01-10'),
    (7, 2, '2017-01-11'),
    (8, 1, '2017-01-12') ;

前一个UPDATE(带有RETURNING *子句)的结果将是:

|----+---------------+---------------------+--------+----+------+-------|
| id | board_list_id |     updated_at      | weight | id | rank | count |
|----+---------------+---------------------+--------+----+------+-------|
| 1  |       1       | 2017-01-09 00:00:00 | 0.1667 | 1  |  1   |   5   |
|----+---------------+---------------------+--------+----+------+-------|
| 2  |       1       | 2017-01-10 00:00:00 | 0.3333 | 2  |  2   |   5   |
|----+---------------+---------------------+--------+----+------+-------|
| 3  |       1       | 2017-01-11 00:00:00 | 0.5    | 3  |  3   |   5   |
|----+---------------+---------------------+--------+----+------+-------|
| 8  |       1       | 2017-01-12 00:00:00 | 0.6667 | 8  |  4   |   5   |
|----+---------------+---------------------+--------+----+------+-------|
| 4  |       1       | 2017-01-12 00:00:00 | 0.6667 | 4  |  4   |   5   |
|----+---------------+---------------------+--------+----+------+-------|
| 5  |       2       | 2017-01-09 00:00:00 | 0.25   | 5  |  1   |   3   |
|----+---------------+---------------------+--------+----+------+-------|
| 6  |       2       | 2017-01-10 00:00:00 | 0.5    | 6  |  2   |   3   |
|----+---------------+---------------------+--------+----+------+-------|
| 7  |       2       | 2017-01-11 00:00:00 | 0.75   | 7  |  3   |   3   |
|----+---------------+---------------------+--------+----+------+-------|