如何针对这种情况编写更好的SQL

时间:2019-08-28 03:26:28

标签: mysql sql

我有一个名为“ DEVICE ”的表,其中包含以下列:

------------------------------------------
SN | User_ID |  State    | ... 
------------------------------------------
1 |  1001   | deployed  | ...
2 |  1001   | deploying | ...
3 |  1002   | inventory | ...
4 |  1003   | deploying | ...
5 |  1001   | deploying | ...
6 |  1002   | synced    | ...
7 |  1002   | synced    | ...
8 |  1010   | synced    | ...
9 |  1008   | unsynced  | ...
---------------------------------------

如您所见,此表列出了所有设备,这些设备通过user_id属于不同的用户。同样对于所有这些设备,它们的状态是以下5种类型之一:

"inventory", 
"deployed", 
"deploying", 
"synced"
"unsynced". 

我需要一个SQL查询,该查询返回的user_id包含每个州的最大设备数。例如,对于第一个表中的上述数据集,返回为:

-----------------------------------------------------------
User_ID     |    State    |   Maximum 
-----------------------------------------------------------
1001        |    deployed |     1 
1001        |    deploying|     2
1002        |    inventory|     1
1002        |    synced   |     2 
1008        |    unsynced |     1 
------------------------------------------------------------

到目前为止,我创建的SQL是这样的:

SELECT 
    STATE, ACCOUNT, CNT 
from 
( select account_id as ACCOUNT, state as STATE, count(*) as CNT 
  from DEVICE group by account_id, state ) T1
where  
    ( STATE, CNT ) 
IN 
    ( select STATE, MAX(CNT) 
from 
( select account_id as ACCOUNT, state as STATE, count(*) as CNT 
   from DEVICE group by account_id, state ) T2 
Group by STATE
);

这太丑了。有更好的方法吗?

谢谢

杰克

4 个答案:

答案 0 :(得分:2)

您可以创建中间摘要表或类似的视图:

drop table if exists device_summary;

create table device_summary as
    select user_id, state, count(*) as counter
    from device
    group by user_id, state;

然后,您可以像这样运行查询以获得所需的结果:

select d.*
from device_summary d
inner join (
    select state, max(counter) as maxcounter
    from device_summary
    group by state
) d1 on d.state = d1.state and d.counter = d1.maxcounter;

示例:https://rextester.com/ZMZH93648

答案 1 :(得分:1)

您可以如下使用... //FontAwesome CSS file wp_enqueue_style( 'epostlite-fontawesome', get_template_directory_uri() . '/fontawesome/css/all.min.css' ); ... 分析函数:

ROW_NUMBER

Ecto.Changeset.force_change/3

干杯!

答案 2 :(得分:0)

尝试一下:

SELECT User_ID, State, count(*) AS Maximum
FROM DEVICE
GROUP BY User_ID, State
ORDER BY User_ID, State

答案 3 :(得分:0)

您可以使用窗口函数,但只需要一级子查询:

SELECT USER_ID, STATE, CNT
FROM (SELECT USER_ID, STATE, COUNT(*) as CNT,
             ROW_NUMBER() OVER (PARTITION BY state ORDER BY COUNT(*) DESC) as seqnum
      FROM DEVICE
      GROUP BY USER_ID, STATE
     ) us
WHERE seqnum = 1;

注意:如果有联系,则返回一个任意用户。如果要全部使用,请使用RANK()而不是ROW_NUMBER()

注意:窗口功能仅在版本8开始的MySQL中可用。