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
Sql 按值对行排序_Sql_Postgresql - Fatal编程技术网

Sql 按值对行排序

Sql 按值对行排序,sql,postgresql,Sql,Postgresql,我尝试按秩对表排序,但具有位置值的行必须根据位置字段中的值具有位置。是否可以在没有其他表、视图等的情况下执行此操作 我有这样的桌子: rank | position | name 999 | 10 | txt1 200 | 4 | txt2 32 | 1 | txt3 1200 | 2 | txt4 123 | null | txt5 234 | null | txt6 567 | null | txt7

我尝试按秩对表排序,但具有位置值的行必须根据位置字段中的值具有位置。是否可以在没有其他表、视图等的情况下执行此操作

我有这样的桌子:

rank | position | name
999  | 10       | txt1
200  | 4        | txt2
32   | 1        | txt3
1200 | 2        | txt4
123  | null     | txt5
234  | null     | txt6
567  | null     | txt7
234  | null     | txt8
432  | null     | txt9
877  | null     | txt10
rank | position | name
32   | 1        | txt3
1200 | 2        | txt4
877  | null     | txt10
200  | 4        | txt2
567  | null     | txt7
432  | null     | txt9
345  | null     | txt8
234  | null     | txt6
123  | null     | txt5    
999  | 10       | txt1
所需的输出必须如下所示:

rank | position | name
999  | 10       | txt1
200  | 4        | txt2
32   | 1        | txt3
1200 | 2        | txt4
123  | null     | txt5
234  | null     | txt6
567  | null     | txt7
234  | null     | txt8
432  | null     | txt9
877  | null     | txt10
rank | position | name
32   | 1        | txt3
1200 | 2        | txt4
877  | null     | txt10
200  | 4        | txt2
567  | null     | txt7
432  | null     | txt9
345  | null     | txt8
234  | null     | txt6
123  | null     | txt5    
999  | 10       | txt1

这里有一个想法。为每一行指定正确的顺序。然后,如果该职位可用,则使用该职位。当存在连接时,将位置值放在第一位:

select t.*
from (select t.*, row_number() over (order by rank desc) as seqnum
      from t
     ) t
order by (case when position is not null then position else seqnum end),
         (case when position is not null then 1 else 2 end);
SQL Fiddle最近似乎不起作用,但此查询显示了结果:

with t(rank, position, t) as (
      select 999, 10, 'txt1' union all
      select 200, 4,  'txt2' union all
      select 32 , 1,  'txt3' union all
      select 1200, 2, 'txt4' union all
      select 123, null, 'txt5' union all
      select 234, null, 'txt6' union all
      select 567, null, 'txt7' union all
      select 234, null, 'txt8' union all
      select 432, null, 'txt9' union all
      select 877, null , 'txt10'
     )
select t.*
from (select t.*, row_number() over (order by rank desc) as seqnum
      from t
     ) t
order by (case when position is not null then position else seqnum end),
         (case when position is not null then 1 else 2 end);
编辑

当我写上面这篇文章时,我对一个问题有一种唠叨的怀疑。这里有一个应该有效的解决方案。它更复杂,但它确实产生了正确的数字:

with t(rank, position, t) as (
      select 999, 10, 'txt1' union all
      select 200, 4,  'txt2' union all
      select 32 , 1,  'txt3' union all
      select 1200, 2, 'txt4' union all
      select 123, null, 'txt5' union all
      select 234, null, 'txt6' union all
      select 567, null, 'txt7' union all
      select 234, null, 'txt8' union all
      select 432, null, 'txt9' union all
      select 877, null , 'txt10'
     )
select *
from (select t.*, g.*,
             row_number() over (partition by t.position order by t.rank) gnum
      from generate_series(1, 10) g(n) left join
           t
           on t.position = g.n
     ) tg left join
     (select t.*,
             row_number() over (partition by t.position order by t.rank) as tnum
      from t
     ) t
     on tg.gnum = t.tnum and t.position is null
order by n;
这是一个奇怪的交叉问题。其思想是使用生成序列为位置创建插槽。然后,将已知位置分配给插槽。最后,枚举剩余的插槽并在其中分配值


注意:我硬编码了10,但很容易从表中输入count*。

这里有一个想法。为每一行指定正确的顺序。然后,如果该职位可用,则使用该职位。当存在连接时,将位置值放在第一位:

select t.*
from (select t.*, row_number() over (order by rank desc) as seqnum
      from t
     ) t
order by (case when position is not null then position else seqnum end),
         (case when position is not null then 1 else 2 end);
SQL Fiddle最近似乎不起作用,但此查询显示了结果:

with t(rank, position, t) as (
      select 999, 10, 'txt1' union all
      select 200, 4,  'txt2' union all
      select 32 , 1,  'txt3' union all
      select 1200, 2, 'txt4' union all
      select 123, null, 'txt5' union all
      select 234, null, 'txt6' union all
      select 567, null, 'txt7' union all
      select 234, null, 'txt8' union all
      select 432, null, 'txt9' union all
      select 877, null , 'txt10'
     )
select t.*
from (select t.*, row_number() over (order by rank desc) as seqnum
      from t
     ) t
order by (case when position is not null then position else seqnum end),
         (case when position is not null then 1 else 2 end);
编辑

当我写上面这篇文章时,我对一个问题有一种唠叨的怀疑。这里有一个应该有效的解决方案。它更复杂,但它确实产生了正确的数字:

with t(rank, position, t) as (
      select 999, 10, 'txt1' union all
      select 200, 4,  'txt2' union all
      select 32 , 1,  'txt3' union all
      select 1200, 2, 'txt4' union all
      select 123, null, 'txt5' union all
      select 234, null, 'txt6' union all
      select 567, null, 'txt7' union all
      select 234, null, 'txt8' union all
      select 432, null, 'txt9' union all
      select 877, null , 'txt10'
     )
select *
from (select t.*, g.*,
             row_number() over (partition by t.position order by t.rank) gnum
      from generate_series(1, 10) g(n) left join
           t
           on t.position = g.n
     ) tg left join
     (select t.*,
             row_number() over (partition by t.position order by t.rank) as tnum
      from t
     ) t
     on tg.gnum = t.tnum and t.position is null
order by n;
这是一个奇怪的交叉问题。其思想是使用生成序列为位置创建插槽。然后,将已知位置分配给插槽。最后,枚举剩余的插槽并在其中分配值


注意:我硬编码了10,但是很容易从表中输入count*。

假设您将数据存储在表1中。 然后,您应该更新列位置,如下所示:

update a
set position = x.pos_null
from table1 
    a
inner join
    (
    select 
        a.name,
        COUNT(a.rank) as pos_null
    from
        (
        select
            *
        from table1
        where position is null
        )
        a
    left join
        (
        select
            *    
        from table1
        )
        b
        on  a.rank <= b.rank
    group by
        a.name
    )
    x
    on  a.name = x.name


select * from table1 order by position 
再见,
Angelo.

假设您将数据存储在表1中。 然后,您应该更新列位置,如下所示:

update a
set position = x.pos_null
from table1 
    a
inner join
    (
    select 
        a.name,
        COUNT(a.rank) as pos_null
    from
        (
        select
            *
        from table1
        where position is null
        )
        a
    left join
        (
        select
            *    
        from table1
        )
        b
        on  a.rank <= b.rank
    group by
        a.name
    )
    x
    on  a.name = x.name


select * from table1 order by position 
再见,
Angelo.

这是一个测试解决方案,但它有bug。例如,在大数字1234134的最后一行中,您可以看到更改排名,这是一个正在测试的解决方案,但它有错误。例如,如果在大数字1234134的最后一行更改排名,您可以看到它