簡體   English   中英

如何針對這種情況編寫更好的SQL

[英]How to write a better SQL for this scenario

我有一個名為“ 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
);

太丑了 有更好的方法嗎?

謝謝,

插口

您可以創建一個中間摘要表或類似的視圖:

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

您可以按以下方式使用ROW_NUMBER分析函數:

SELECT
    B.USER_ID,
    B.STATE,
    B.CNT
FROM
    (
        SELECT
            ROW_NUMBER() OVER(
                PARTITION BY A.STATE
                ORDER BY
                    A.CNT DESC
            ) AS RN,
            A.USER_ID,
            A.STATE,
            A.CNT
        FROM
            (
                SELECT
                    USER_ID,
                    STATE,
                    COUNT(1) CNT
                FROM
                    DEVICE
                GROUP BY
                    USER_ID,
                    STATE
            ) A
    ) B
WHERE
    B.RN = 1

db <> fiddle演示

干杯!!

嘗試這個:

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

您可以使用窗口函數,但只需要一個子查詢級別:

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中可用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM