Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在PostgreSQL中将行转换为列?_Sql_Postgresql_Sql Order By_Jooq - Fatal编程技术网

如何在PostgreSQL中将行转换为列?

如何在PostgreSQL中将行转换为列?,sql,postgresql,sql-order-by,jooq,Sql,Postgresql,Sql Order By,Jooq,我有两个数据库表,如下所示 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

我有两个数据库表,如下所示

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

这是一个示例,可以在sqlserver中执行您想要的操作。你应该能够适应深造

我有两个版本,一个是硬编码排序,第二个是使用参数来决定排序依据

首先在临时表变量中创建数据

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
具有参数列排序的第二个版本

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

这是一个示例,可以在sqlserver中执行您想要的操作。你应该能够适应深造

我有两个版本,一个是硬编码排序,第二个是使用参数来决定排序依据

首先在临时表变量中创建数据

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
具有参数列排序的第二个版本

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

好的,这很容易实现,只需使用
自连接
,如下所示:

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
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)
好的,有一个名为交叉表的函数,它可以将行转换为列,我认为它将完全满足您的需要,如下所示:

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
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)
哦,对了,在使用
交叉表
函数之前,应该在PostgreSQL中执行下面的子句,否则会出现错误

CREATE EXTENSION tablefunc;

好的,这很容易实现,只需使用
自连接
,如下所示:

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
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)
好的,有一个名为交叉表的函数,它可以将行转换为列,我认为它将完全满足您的需要,如下所示:

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
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)
哦,对了,在使用
交叉表
函数之前,应该在PostgreSQL中执行下面的子句,否则会出现错误

CREATE EXTENSION tablefunc;

你能举例说明结果吗?让我们更清楚地了解你想要什么。肖恩-我已经用一个示例结果更新了问题,我想给出答案。希望这对你有所帮助。你能给出一个示例结果吗?让我们更清楚地了解您想要什么。Shawn-我已经用示例结果更新了问题,我想给出答案。希望这对您有所帮助。谢谢Shawn。是否有一种方法可以使查询具有通用性,从而可以容纳任意数量的资产类型?目前,我只有3种资产类型,但用户在未来最多可以添加30种。在这种情况下,我不想加入30次,因为这会大大降低查询速度。好的,让我想想,然后给你一个更完美的答案,稍等几分钟。@user1066568我已经更新了我的答案,我认为它会完美地解决你的问题。祝你好运!谢谢,肖恩。是否有一种方法可以使查询具有通用性,从而可以容纳任意数量的资产类型?目前,我只有3种资产类型,但用户在未来最多可以添加30种。在这种情况下,我不想加入30次,因为这会大大降低查询速度。好的,让我想想,然后给你一个更完美的答案,稍等几分钟。@user1066568我已经更新了我的答案,我认为它会完美地解决你的问题。祝你好运!