SQL查询表,其顺序在相邻表中定义

时间:2019-09-06 10:47:41

标签: sql postgresql

我需要从表accounts返回不同的记录,首先显示状态为off的设备。

enter image description here

所以结果应该是:

enter image description here

我正在尝试将记录分组

SELECT account.id, account.name FROM account
  LEFT JOIN devices ON account.id = devices.account_id
  GROUP BY account.id, devices.status
  ORDER BY devices.status desc

但是account # 2在列表中出现了两次,因为它同时具有两个on/off设备

5 个答案:

答案 0 :(得分:1)

您基本上可以进行基于条件聚合的排序。以下查询将对帐户是否关闭任何设备进行第一级排序。至少有一个设备off的所有帐户都被视为处于同一级别进行排序。第二级排序是在account_id上进行的(用于平局决胜)。

SELECT account.id, account.name 
FROM account
LEFT JOIN devices ON account.id = devices.account_id
GROUP BY account.id, account.name
ORDER BY MAX(CASE devices.status WHEN 'off' THEN 1 ELSE 0 END) DESC, 
         account.id

SQL Fiddle Demo (感谢 @Martin


现在,如果您希望使该帐户的“关闭”设备数最多,我们可以使用以下查询:

SELECT account.id, account.name 
FROM account
LEFT JOIN devices ON account.id = devices.account_id
GROUP BY account.id, account.name
ORDER BY SUM(CASE devices.status WHEN 'off' THEN 1 ELSE 0 END) DESC, 
         account.id

答案 1 :(得分:0)

使用条件排序:

select a.* 
from account a 
order by exists (
  select 1 from devices
  where account_id = a.id and status = 'off'
) desc  

请参见demo
结果:

| id  | name |
| --- | ---- |
| 2   | B    |
| 1   | A    |

答案 2 :(得分:0)

即使您的帐户中有一些device记录处于“关闭”状态,而某些帐户处于“开启”状态,下面的查询仍然有效,它会使用ROW_NUMBER()对同一帐户中的device条记录进行排序-选择一个(优先考虑处于“关闭”状态的帐户),然后根据这些帐户记录是“关闭”还是“开启”来排序:

select accountId, accountName
from(
    select ROW_NUMBER() OVER(
        PARTITION BY account_id
        ORDER BY status1
    ) as rn
    , device.id
    , device.account_id
    , device.status1 as deviceStatus
    , account.id as accountId 
    , account.name as accountName
    from device
    join account on account.id = device.account_id
  ) as tableWithRowNumbers
 where rn = 1
 order by deviceStatus

这是SQL提琴:http://sqlfiddle.com/#!15/e04a0/19

在我的示例中,列状态称为status1。

答案 3 :(得分:0)

如果一台设备最多可以有一个“关闭”记录(例如您的示例),并且所有帐户都有设备,则可以使用:

SELECT a.id, a.name
FROM account a LEFT JOIN
     devices d
     ON a.id = d.account_id AND d.status = 'OFF'
ORDER BY d.status NULLS FIRST;

我很好奇您想按状态排序,但不将其包括在SELECT中。您如何知道状态在结果集中的变化位置?

答案 4 :(得分:0)

这是我最终使用的内容:

select "stores".*, "account"."country", "account"."name" as "account", "store_devices"."disconnected_num"
  from "stores" left join "accounts" as "account" on "account"."id" = "stores"."account_id"
  left join (
    SELECT store_id, COUNT(DISTINCT CASE WHEN id > 0 THEN 1 ELSE 0 end) AS disconnected_num
    FROM devices WHERE status = 'OFF'
    GROUP BY store_id
  ) AS store_devices
on "store_devices"."store_id" = "stores"."id"
order by "disconnected_num" asc