2016-05-13 14 views
0

Reihe haben wie:Postgresql wählen Sie die zwei Top-Städte

user | town 1 | town 2 | town 3 | town 4 | town 5 | town 6| 

Die Gemeinden, alle ganzzahligen Werte haben, wo Stadt 3 und Stadt 4 die größte Zahl haben

Ich möchte die beiden Top-Städte für die Auswahl Benutzer so das Endergebnis sollte sein:

user | town 3 | town 4 | 
+1

Mit einem ordnungsgemäß normalisierten Modell wäre dies einfach. Warum speichern Sie diese Informationen in mehreren Spalten? Warum bringst du das nicht in eine richtige 1: Viele-Beziehung –

Antwort

2

Dies ist das richtig normalisiert Modell ist:

create table users (
    user_id serial primary key, 
    user_name varchar(100) 
); 

create table town (
    town_id serial primary key, 
    town_int int 
); 

create table user_town (
    town_id int references town (town_id), 
    user_id int references users (user_id), 
    primary key (user_id, town_id) 
); 

insert into users (user_name) values ('John'); 
insert into town (town_int) values (1),(2),(3),(4),(5),(6); 
insert into user_town (user_id, town_id) values (1,1),(1,2),(1,3),(1,4),(1,5),(1,6); 

Wie es abfragen:

select user_id, user_name, town_id, town_int 
from 
    user_town 
    inner join 
    users using (user_id) 
    inner join 
    town using (town_id) 
where user_id = 1 
order by town_int desc 
limit 2 
; 
user_id | user_name | town_id | town_int 
---------+-----------+---------+---------- 
     1 | John  |  6 |  6 
     1 | John  |  5 |  5 
0

Somtimes haben wir genau das, was wir, schlecht konzipiert Vermächtnis DB zum Beispiel. Dann

WITH t AS (
SELECT 100 as userid, 11 as town1, 23 as town2, 77 as town3, 14 as town4, 15 as town5, 16 as town6 
UNION ALL 
SELECT 101 as userid, 21 as town1, 235 as town2, 177 as town3, 24 as town4, 25 as town5, 26 as town6 
) 
SELECT userid, max(r.town) as top1, min(r.town) as top2 
FROM t 
CROSS JOIN LATERAL(
    SELECT town1 as town FROM t t2 WHERE t2.userid=t.userid 
    UNION ALL 
    SELECT town2 FROM t t2 WHERE t2.userid=t.userid 
    UNION ALL 
    SELECT town3 FROM t t2 WHERE t2.userid=t.userid 
    UNION ALL 
    SELECT town4 FROM t t2 WHERE t2.userid=t.userid 
    UNION ALL 
    SELECT town5 FROM t t2 WHERE t2.userid=t.userid 
    UNION ALL 
    SELECT town6 FROM t t2 WHERE t2.userid=t.userid 
    ORDER BY town DESC LIMIT 2) AS r 
GROUP BY userid; 
Verwandte Themen