我有两个如下的数据库表
site
id | name
1 Site One
2 Site Two
3 Site Three
asset_quantities
id | site_id | asset_type | quantity
1 1 1 10
2 1 2 15
3 1 3 25
4 2 1 11
5 2 2 16
6 2 3 7
7 3 1 12
8 3 2 15
9 3 3 16
我想编写一个SQL查询,该查询将根据给定资产类型的“数量”列对结果进行排序 例如。我想基于所有站点上资产类型1的数量对降序结果进行排序。 对于这种情况,我将如何构建SQL查询?
如果要在所有站点上对资产类型1的数量进行降序排序,下面是我想要的示例结果
site_id | asset_type_1_qty | asset_type_2_qty | asset_type_3_qty
3 12 15 16
2 11 16 7
1 10 15 25
答案 0 :(得分:0)
这是一个可以在sqlserver中完成所需操作的示例。您应该能够使其适应Postgres。
我有两个版本,一个版本对排序进行硬编码,第二个版本使用参数来决定排序的依据。
首先在临时表变量中创建数据
declare @s table(id int, site_id int, asset_type int, quantity int)
insert @s values (1,1,1,10)
,(2,1,2,15)
,(3,1,3,25)
,(4,2,1,11)
,(5,2,2,16)
,(6,2,3,7)
,(7,3,1,12)
,(8,3,2,15)
,(9,3,3,16)
具有固定列排序的第一版
select site_id,
max(case when asset_type=1 then quantity else 0 end) as q1,
max(case when asset_type=2 then quantity else 0 end) as q2,
max(case when asset_type=3 then quantity else 0 end) as q3
from @s
group by site_id
order by 2 desc
带有参数列排序的第二个版本
declare @assetsort int;
set @assetsort=3
select * from (
select site_id,
max(case when asset_type=1 then quantity else 0 end) as q1,
max(case when asset_type=2 then quantity else 0 end) as q2,
max(case when asset_type=3 then quantity else 0 end) as q3
from @s
group by site_id
) q
order by
case @assetsort when 1 then q1 when 2 then q2 when 3 then q3 end desc
答案 1 :(得分:0)
好的,很容易实现,只需使用self join
,如下所示:
select
s1.site_id,
s1.quantity as asset_type_1_qty,
s2.quantity as asset_type_2_qty,
s3.quantity as asset_type_3_qty
from
asset_quantities s1
join
asset_quantities s2 on s1.site_id=s2.site_id and s1.asset_type=1 and s2.asset_type=2
join
asset_quantities s3 on s1.site_id=s3.site_id and s3.asset_type=3
order by
s1.quantity desc
好的,有一个名为crosstab
的函数可以将行转换为列,我认为它可以完全满足您的需求,如下所示:
postgres=# select * from asset_quantities;
id | site_id | asset_type | quantity
----+---------+------------+----------
1 | 1 | 1 | 10
2 | 1 | 2 | 15
3 | 1 | 3 | 25
4 | 2 | 1 | 11
5 | 2 | 2 | 16
6 | 2 | 3 | 7
7 | 3 | 1 | 12
8 | 3 | 2 | 15
9 | 3 | 3 | 16
(9 rows)
postgres=# select * from crosstab(
'select
site_id,
asset_type,
quantity
from
asset_quantities order by site_id,asset_type'
) as result(site_id int,asset_type_1_qty int,asset_type_2_qty int,asset_type_3_qty int);
site_id | asset_type_1_qty | asset_type_2_qty | asset_type_3_qty
---------+------------------+------------------+------------------
1 | 10 | 15 | 25
2 | 11 | 16 | 7
3 | 12 | 15 | 16
(3 rows)
哦,对了,在使用crosstab
函数之前,应该在PostgreSQL中执行下面的子句,否则会出现错误。
CREATE EXTENSION tablefunc;