Выберите определенные столбцы по их псевдониму, а затем упорядочите по нему

#sql #postgresql #sql-order-by

#sql #postgresql #sql-order-by

Вопрос:

Моя таблица выглядит следующим образом

  ---- ---------- -------- 
| id | priority |  User  |
 ---- ---------- -------- 
|  1 |        2 | [null] |
|  2 |        1 | [null] |
|  3 |        3 | Tony   |
|  4 |        2 | John   |
|  5 |        2 | Andy   |
|  6 |        1 | Mike   |
 ---- ---------- -------- 
 

Моя цель — извлечь их и упорядочить по следующим комбинированным условиям:

  1. приоритет = 1
  2. Пользователь имеет значение null
  ---- ---------- -------- ----------- 
| id | priority |  User  | peak_rows |
 ---- ---------- -------- ----------- 
|  1 |        2 | [null] | 1         |
|  2 |        1 | [null] | 1         |
|  6 |        1 | Mike   | 0         |
|  3 |        3 | Tony   | 1         |
|  4 |        2 | John   | 0         |
|  5 |        2 | Andy   | 0         |
 ---- ---------- -------- ----------- 
 

Это то, что, я думаю, я могу сделать

 select
    id,
    CASE WHEN priority = 1 THEN 1 ELSE 0 END as c1,
    CASE WHEN User is NULL THEN 1 ELSE 0 END as c2,
    c1   c2 AS peak_rows
FROM mytable
ORDER BY peak_rows DESC
 

но это вызывает ошибку:

 ERROR:  column "c1" does not exist
LINE 5:  c1  c2as pp
         ^
SQL state: 42703
Character: 129
 

Я не знаю, почему я создаю 2 столбца (c1 и c2), но я не могу использовать его позже.

Есть хорошая идея сделать это?

Ответ №1:

Вы не создаете два столбца и используете их позже, вы создаете их и хотите использовать их одновременно. Вы могли бы использовать подзапрос.

 SELECT a.id, a.priority, a.User, a.c1   a.c2 AS peak_rows
FROM
(SELECT id,
        priority,
        User,
        CASE WHEN priority = 1 THEN 1 ELSE 0 END as c1,
        CASE WHEN User IS NULL THEN 1 ELSE 0 END as c2,
 FROM mytable) a
ORDER BY peak_rows DESC;

 

Ответ №2:

 select
    id,
    CASE WHEN priority = 1 THEN 1 ELSE 0 END as c1,
    CASE WHEN User is NULL THEN 1 ELSE 0 END as c2,
    (CASE WHEN priority = 1 THEN 1 ELSE 0)   ( CASE WHEN User is NULL THEN 1 ELSE 0 END) AS peak_rows
FROM mytable
ORDER BY peak_rows DESC
 

Комментарии:

1. Спасибо, я думаю, это тоже работает, но я не хочу повторять код.

Ответ №3:

Я полагаю, ваша цель — упорядочить по этим c1 и c2 , чтобы вы могли напрямую использовать в order by предложении. Вам просто нужно поменять 0 местами и 1 в case..when операторах. И в зависимости от ваших priority=1 критериев id=2 должны оставаться на вершине.

 with mytable( id, priority, "User" ) as
(
 select 1 , 2,  null  union all
 select 2,  1,  null  union all
 select 3,  3, 'Tony' union all
 select 4,  2, 'John' union all
 select 5,  2, 'Andy' union all
 select 6,  1, 'Mike'
)    
select * 
  from mytable
 order by ( case when priority = 1   then 0 else 1 end )  
          ( case when "User" is null then 0 else 1 end );

id  priority   User
--  -------- -------
2   1         [null]
1   2         [null]
6   1          Mike
3   3          Tony
4   2          John
5   2          Andy
 

Demo