2016-05-13 41 views
0

有行,如:PostgreSQL的选择两个顶部城镇

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

城镇都有整数值,其中镇3镇4拥有最大数量

我想选择的两个顶部城镇用户因此最终的结果应该是:

user | town 3 | town 4 | 
+1

有了正确的标准化模型,这很容易。为什么你将这些信息存储在多个列中?你为什么不把它变成适当的1:多关系 –

回答

2

这是正确的标准化模型:

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); 

如何查询它:

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我们刚才我们所拥有的,例如穷人设计的传统DB。然后

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;