[SQL] ottaa jokaisen käyttäjän viimeisin tietue (ryhmä ottaa Top n: n)

Take Most Recent Record Each User



Minulla ei ole ehtinyt kirjoittaa ja jakaa ja lopulta odottaa kaksitoista yksitoista, mitään kysyntää ei sallita, tällä kertaa aikaa viemään useita päiviä kerätyn SQL: n selvittämiseen.

Edellytys: Löysin käyttäjän viimeisimmän kirjautumistietueen. (110w)



Edellytys: Oletusaika ja tunnus ovat molemmat lisäykset. (Maksimoi aika -> pyydä enimmäistunnusta)



The first type: select * from user_login_log where id in (select max (id) from user_login_log group by user_id) takes 6.35s Second: select * from user_login_log where exists (select max(id) from user_login_log group by user_id) takes 3.47s The third type: select * from user_login_log a join (select max(id) as id from user_login_log group by user_id) b on a.id=b.id takes 3.65s The fourth type: select * from user_login_log a , (select max(id) as id from user_login_log group by user_id) b where a.id=b.id takes 3.65s The fifth type: select * from user_login_log a where 1>=(select count(1) from user_login_log b where a.user_id=b.user_id and a.id<=b.id) order by user_id , id desc takes 1000s+ Sixth: select *, GROUP_CONCAT(login_ip_str order by id desc) from user_login_log group by user_id It takes 200.32s Seventh: select * from(SELECT (@row_number:=CASE WHEN @customer_no = user_id THEN @row_number + 1 ELSE 1 END) AS num, @customer_no:=user_id AS user_id, id, login_ip_str,created_date FROM user_login_log ORDER BY user_id ,created_date desc)x where x.num=1 takes 24.1s

Vaihtoehto 1: in + max ()



Selitys: Valitse enimmäistunnus kullekin käyttäjälle ja kysele sitten painamalla in. Sopii kaikille tietokannoille,

Vaihtoehto 2: olemassa + max ()

Selitys: Valitse enimmäistunnus kullekin käyttäjälle. Käytä sitten tämän id: n ja taulukon id: tä missä ehto plus select 1, koska sisällön olemassaolo on olemassa.



Vaihtoehto 3: Liity + max ()

Selitys: Valitse enimmäistunnus kullekin käyttäjälle. Ota sitten koko liittymispöytä id: n mukaan ja poista kaikki id: tä vastaavat tiedot.

Vaihtoehto 4: missä + max ()

Selitys: Missä yhteinen tarkistus optimoidaan liittymiskyselyksi, kaikki tehosteet ja samat kolme.

Vaihtoehto 5: Itseyhdistys + laskenta ()

Selitys: Ajatuksena on arvioida, onko jokaisessa tietueessa useita paikallista suurempia tietueita. Jos vain yksi on suurempi kuin itse, se on johdonmukaista. Suodata kaikki tietueet ja lajittele lopuksi ryhmän nimen ja arvon mukaan. Mutta hän ei laskenut (*) laskutoimitusta, joten suorituskyky oli heikko.

Vaihtoehto 6: GROUP_CONCAT + sieppaus

Selitys: Käytä ryhmän_CONCAT lajittelutoimintoa , lajittele ja liitä kaikkien käyttäjien tietueet yhteen kenttään ja siepata sitten ensimmäinen kohde. Koskee mysql-tiedostoa, mutta tämä menetelmä on hyvin tehoton. Menetelmä voi palauttaa vain viimeisimmän kentän, jos sinun on palautettava kaikki tiedot toiminnon viimeisimmän käyttötarpeen * käytöstä, joten yleensä tee vain idea.

Vaihtoehto 7: Väliaikaiset muuttujat

Selitys: Itse asiassa sen on määritettävä, onko nykyisen rivin user_id arvo sama kuin edellisen rivin user_id arvo. Kun se ei ole sama, se numeroidaan uudelleen (lähtö 1), jolloin toteutetaan ryhmittelysekvenssin numerointitoiminto. (Tapauksessa, jossa arviointiehto on ennen asiakas_no-määritystä), tämä muutaman viimeisen laskelma, voit määrittää ajan lyhentämisen rajan, lyhennettynä 1 sekuntiin.

1. Niistä viisi, kuusi ja seitsemän voivat paitsi saavuttaa uusimman, myös Top n -vaatimukset, joita voidaan käyttää rivin ROW_NUMBER () sijaan (PARTITION BY xx ORDER BY ** DESC) sijaan, mutta kaavion 7: llä on parempi suorituskyky.

2. Hive, Oracle, SqlServer käyttää yleensä riviä ROW_NUMBER () yli (PARTITION BY xx ORDER BY ** DESC) saavuttaakseen ongelman, joka liittyy ryhmään Top n.

3. mysql8: lla ei ole aikaisemmin ikkunointitoimintoa, joten se voidaan toteuttaa vain järjestelmän viiden ja kaavion seitsemän kautta.

Tervetuloa lisäämään ~!