我有这张桌子:
lnumber | lname | bez_gem
---------+----------------+------------------------------
1 | name1 | Berg b.Neumarkt i.d.OPf.
1 | name1 | Altdorf b.Nürnberg
2 | name2 | Berg b.Neumarkt i.d.OPf.
2 | name2 | Altdorf b.Nürnberg
3 | name3 | Mainleus
3 | name3 | Weismain
4 | name4 | Weismain
4 | name4 | Mainleus
查询的代码是:
WITH double AS (
SELECT
partnumber,
bez_gem
FROM accumulation a, municipality b
WHERE ST_Intersects(a.geom, b.geom)
AND EXISTS (
SELECT
lnumber
FROM mun_more_than_once c
WHERE a.partnumber=c.lnumber)
ORDER BY partnumber)
SELECT
landslide.lnumber,
lname,
bez_gem
FROM double, landslide
WHERE double.partnumber=landslide.lnumber
ORDER BY lnumber
我想以这种格式进行转置
lnumber | lname | bez_gem1 | bez_gem2
---------+----------------+------------------------------------------------
1 | name1 | Berg b.Neumarkt i.d.OPf. | Altdorf b.Nürnberg
2 | name2 | Berg b.Neumarkt i.d.OPf. | Altdorf b.Nürnberg
答案 0 :(得分:1)
这取决于。如果每bez_gem
总共有两个lnumber
,则可以使用:
SELECT lnumber, lname
, min(bez_gem) AS bez_gem1
, max(bez_gem) AS bez_gem2
FROM test
GROUP BY 1,2
ORDER BY 1;
请注意,您的问题中未定义同伴的顺序。整理规则(字母顺序)在我的例子中决定。
对于实际交叉制表,您可以使用附加模块tablefunc中的crosstab()
功能。但是您的表缺少类别名称(没有指示哪一行包含bez_gem1
以及哪个bez_gem2
)。说明,细节和链接:
PostgreSQL Crosstab Query
答案 1 :(得分:0)
数据
-- drop table if exists test;
create table test (lnumber int, lname varchar, bez_gem varchar);
insert into test values
(1 , 'name1' , 'Berg b.Neumarkt i.d.OPf.'),
(1 , 'name1' , 'Altdorf b.Nürnberg'),
(2 , 'name2' , 'Berg b.Neumarkt i.d.OPf.'),
(2 , 'name2' , 'Altdorf b.Nürnberg'),
(3 , 'name3' , 'Mainleus'),
(3 , 'name3' , 'Weismain'),
(4 , 'name4' , 'Weismain'),
(4 , 'name4' , 'Mainleus'),
(4 , 'name4' , 'XXMainleus')
;
查询
select
lnumber,
lname,
max(case when rn = 1 then bez_gem end) as bez_gem1,
max(case when rn = 2 then bez_gem end) as bez_gem2,
max(case when rn = 3 then bez_gem end) as bez_gem3
from
(
select
*,
row_number() over(partition by lname) rn
from
test
) a
group by
lnumber,
lname
结果
1;name1;Berg b.Neumarkt i.d.OPf.;Altdorf b.Nürnberg;
2;name2;Berg b.Neumarkt i.d.OPf.;Altdorf b.Nürnberg;
3;name3;Mainleus;Weismain;
4;name4;Weismain;Mainleus;XXMainleus
旧答案
如果每个lnumber
只有两个可能的行(您应该将这些重要信息添加到您的问题中),您只需使用min
和max
:
WITH double AS (
SELECT
partnumber,
bez_gem
FROM accumulation a, municipality b
WHERE ST_Intersects(a.geom, b.geom)
AND EXISTS (
SELECT
lnumber
FROM mun_more_than_once c
WHERE a.partnumber=c.lnumber)
ORDER BY partnumber)
SELECT
landslide.lnumber,
lname,
min(bez_gem) as bez_gem1,
max(bez_gem) as bez_gem2
FROM double, landslide
WHERE double.partnumber=landslide.lnumber
group by
landslide.lnumber,
lname
ORDER BY lnumber
如果每个lnumber
可能有两行以上,并且您确实需要交叉表,那么在SO(example)上的PostgreSQL中有很多关于交叉表的问题。作为替代方案,您可以尝试以下方法。
由于这是一次性分析,因此您可以轻松获得最大数量的唯一bez_gem
值:
select
landslide.lnumber,
count(distinct bez_gem) cnt
from
<<some_data>>
group by
landslide.lnumber
order by
cnt desc limit 1
然后你可以使用:
select
landslide.lnumber,
lname,
max(case when rn=1 then bez_gem end) as bez_gem1,
max(case when rn=2 then bez_gem end) as bez_gem2,
max(case when rn=3 then bez_gem end) as bez_gem3,
max(case when rn=4 then bez_gem end) as bez_gem4,
max(case when rn=5 then bez_gem end) as bez_gem5,
... up to cnt ...
from(
select
landslide.lnumber,
lname,
bez_gem,
row_number() over(partition by landslide.lnumber) rn
from
<<some_data>>
) a
group by
landslide.lnumber,
lname
对于您的数据和5个可能的值,它们看起来像:
WITH double AS (
SELECT
partnumber, bez_gem
FROM
accumulation a, municipality b
WHERE
ST_Intersects(a.geom, b.geom)
AND EXISTS (
SELECT lnumber
FROM mun_more_than_once c
WHERE a.partnumber=c.lnumber)
ORDER BY
partnumber
)
select
landslide.lnumber,
lname,
max(case when rn=1 then bez_gem end) as bez_gem1,
max(case when rn=2 then bez_gem end) as bez_gem2,
max(case when rn=3 then bez_gem end) as bez_gem3,
max(case when rn=4 then bez_gem end) as bez_gem4,
max(case when rn=5 then bez_gem end) as bez_gem5
from (
select
landslide.lnumber,
lname,
bez_gem,
row_number() over(partition by landslide.lnumber) rn
from
double, landslide
where
double.partnumber=landslide.lnumber
) a
group by
landslide.lnumber,
lname