Duplikate auf bestimmte Anzahl begrenzen

jmar83

SQL-Guru
Beiträge
146
Doppelte Einträge sollten max. 3x drin sein, gibt es eine bessere Lösung als das?

SELECT DISTINCT `et`.`code` FROM xyz et WHERE `et`.`timestamp` > (TIMESTAMPADD(SECOND, -15, NOW()))
UNION ALL
SELECT DISTINCT `et`.`code` FROM xyz et WHERE `et`.`timestamp` > (TIMESTAMPADD(SECOND, -15, NOW()))
UNION ALL
SELECT DISTINCT `et`.`code` FROM xyz et WHERE `et`.`timestamp` > (TIMESTAMPADD(SECOND, -15, NOW()))

Danke für die Feedbacks.
 
Werbung:
Nein ist auch keine Lösung, wenn es nur 1 oder 2x drin ist wird es ebenfalls auf 3 vervielfacht. Ab > 3 sollte auf 3 begrenzt werden, drunter sollte die real in der Tabelle hinterlegte Menge ausgegeben werden.
 
Du willst nur max. 3 gleiche Einträge selecten?

Code:
test=# create table jmar83 (i int);
CREATE TABLE
test=*# insert into jmar83 select (random()*5) from generate_series(1,20) s;
INSERT 0 20
test=*# select * from jmar83 ;
 i
---
 4
 1
 2
 1
 4
 4
 4
 1
 2
 4
 5
 2
 2
 2
 5
 4
 2
 3
 2
 2
(20 rows)

test=*# with x as (select i, row_number() over (partition by i) from jmar83) select i from x where row_number <= 3;
 i
---
 1
 1
 1
 2
 2
 2
 3
 4
 4
 4
 5
 5
(12 rows)

test=*#
 
...und die Zeitfunktionen sind ebenfalle ein Problem, hintereinander aufgerufen = Abweichung

in dem von dir gezeigten context nicht:

Code:
test=*# \timing
Timing is on.
test=*# select now(), pg_sleep(2) union all select now(),pg_sleep(2) union all select now(), pg_sleep(2);
              now              | pg_sleep
-------------------------------+----------
 2019-04-04 13:40:05.480755+02 |
 2019-04-04 13:40:05.480755+02 |
 2019-04-04 13:40:05.480755+02 |
(3 rows)

Time: 6006,838 ms (00:06,007)
test=*#

Zumindest nicht in PG, da now() den Startzeitpunkt der Transaktion liefert. Was anderes wäre clock_timestamp()

Code:
test=*# select clock_timestamp(), pg_sleep(2) union all select clock_timestamp(),pg_sleep(2) union all select clock_timestamp(), pg_sleep(2);
        clock_timestamp        | pg_sleep
-------------------------------+----------
 2019-04-04 13:45:53.009689+02 |
 2019-04-04 13:45:55.011845+02 |
 2019-04-04 13:45:57.013918+02 |
(3 rows)

Time: 6006,876 ms (00:06,007)
test=*#

das liefert dir, auch in einer Transaktion, die tatsächliche Zeit.
 
Vielen Dank für Dein schnelles Feedback.

"Du willst nur max. 3 gleiche Einträge selecten?"

Exakt. Allerdings werd ich aus diesem Statement (SELECT?) nicht ganz schlau:

test=*# with x as (select i, row_number() over (partition by i) from jmar83) select i from x where row_number <= 3;
 
Okay, das ist Syntax von PostgreSQL. Das kann man umschreiben in ein Subselect:

Code:
test=*# select * from (select i, row_number() over (partition by i) from jmar83) x where row_number <= 3;
 i | row_number
---+------------
 1 |          1
 1 |          2
 1 |          3
 2 |          1
 2 |          2
 2 |          3
 3 |          1
 4 |          1
 4 |          2
 4 |          3
 5 |          1
 5 |          2
(12 rows)

Time: 0,537 ms

Allerdings kennen viele MySQL-Versionen kein row_number().
 
Werbung:
Zurück
Oben