0

我有下面的查询,它在 MySQL 中有效,但在 Postgresql 中失败,并出现以下错误:

ERROR:  column "status" does not exist

我们如何在 Postgresql 中实现这一点?

select
    devices.*,
    CASE
        WHEN devices.retired = false
        AND devices.last_reported_utc_at > '2020-12-23 07:13:52'
        AND SUM(device_measurements.flow) > 0 THEN 'active'
        WHEN devices.retired = false
        AND devices.last_reported_utc_at > '2020-12-23 07:13:52'
        AND SUM(device_measurements.flow) = 0 THEN 'online'
        WHEN devices.retired = false
        AND devices.last_reported_utc_at <= '2020-12-23 07:13:52' THEN 'offline'
        WHEN devices.retired = false
        AND devices.serial_number IS NULL THEN 'inactive'
        WHEN devices.retired = true THEN 'retired'
    END AS status,
    MAX(devices_meters.activated_at) AS activated_at,
    MAX(devices_meters.created_at) AS latest
from
    devices
    left join devices_meters on devices_meters.device_id = devices.id
    left join device_measurements on device_measurements.device_id = devices.id
group by
    devices.id,
    devices_meters.activated_at
having
    status = "offline"
order by
    devices.installed_at desc
4

1 回答 1

2

有几种解决方案。

  • 使用子查询
  • 使用 CTE(有)
  • 使用横向连接

后者有我的偏好,这是我将如何实现它:

select
    devices.*,
    lt.status,
    MAX(devices_meters.activated_at) AS activated_at,
    MAX(devices_meters.created_at) AS latest
from
    devices
    left join devices_meters on devices_meters.device_id = devices.id
    left join device_measurements on device_measurements.device_id = devices.id
left join lateral (
  SELECT
    CASE
        WHEN devices.retired = false
        AND devices.last_reported_utc_at > '2020-12-23 07:13:52'
        AND SUM(device_measurements.flow) > 0 THEN 'active'
        WHEN devices.retired = false
        AND devices.last_reported_utc_at > '2020-12-23 07:13:52'
        AND SUM(device_measurements.flow) = 0 THEN 'online'
        WHEN devices.retired = false
        AND devices.last_reported_utc_at <= '2020-12-23 07:13:52' THEN 'offline'
        WHEN devices.retired = false
        AND devices.serial_number IS NULL THEN 'inactive'
        WHEN devices.retired = true THEN 'retired'
    END AS status
  ) AS lt ON TRUE
group by
    devices.id,
    devices_meters.activated_at
having
    lt.status = "offline"
order by
    devices.installed_at desc

现在,虽然这解决了在查询中随处可用状态的问题,但 GROUP BY 存在另一个问题,它需要包含 devices.* 和 lt.status,但这超出了我认为的这个问题的范围。

于 2020-12-24T07:34:59.467 回答