我需要从表accounts
返回不同的记录,首先显示状态为off
的设备。
所以结果应该是:
我正在尝试将记录分组
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
设备
答案 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