Crosstab Postgres 和 PHP 准备好的语句

Crosstab Postgres and PHP prepared statements

我找不到这个问题的解决方案:我有这个 table:

Model    | Date           |  Status    | ...
A        | 21-10-2020     |     Ok     | ...
B        | 21-10-2020     |     Ok     | ...
C        | 21-10-2020     |   Warning  | ...
A        | 19-10-2020     |    Error   | ...
B        | 19-10-2020     |    Warning | ...
...

我想得到这个:

Model    |  Ok   | Warning | Error
A        |   1   |    0    | 1
B        |   1   |   1     | 0
C        |   0   |   1     | 0
...

我找到了使用交叉表的可能解决方案

SELECT * FROM  crosstab(
    $$SELECT "Model", "Status", count(1)
    FROM  table
    WHERE "Date" < $$ ||  || $$
    AND "Date" > $$ ||  || $$
    GROUP  BY 1,2
    ORDER  BY 1,2
    $$,
    $$VALUES (\'Ok\'::text), (\'Warning\'), (\'Error\')$$ )
    as ct ("Model" text, "Ok" int, "Warning" int,
      "Error" int)'

在 php 中使用准备好的语句,其中 $1 和 $2 是日期。 无论如何,我得到这个错误:

operator does not exist: timestamp without time zone < integer LINE 3: WHERE "Date" < 2020-02-18

日期被视为整数,即使我使用 cast($1 as text)(或日期,或时间戳,..)

有人可以帮助我吗?

您需要将绑定值转换为正确的数据类型。我还建议使用条件聚合而不是 crosstab:这可能是个人喜好问题,但我发现它更容易遵循。它也更灵活(尽管在这个简单的情况下这没有什么不同)。

所以:

select model,
    count(*) filter(where status = 'OK') as ok,
    count(*) filter(where status = 'Warning') as warning,
    count(*) filter(where status = 'Error') as error
from mytable
where date < ::timestamp and date > ::timestamp
group by model