Используйте значение столбца выражения CASE в другом выражении CASE в SQL Запрос - PullRequest
0 голосов
/ 23 апреля 2020

Я пытаюсь использовать один столбец, полученный из выражения CASE, для установки другого значения столбца.

EG У меня есть пользователь таблицы с несколькими столбцами. Во-первых, мне нужно установить статус проекта на основе значений некоторых столбцов в таблице. Я могу заставить эту часть работать. Вторая часть, в зависимости от значения статуса, мне нужно получить имена пользователей из нескольких столбцов. Когда я это делаю, я получаю сообщение об ошибке

Недопустимый столбец «Статус»

Пример запроса следующий:

  SELECT
  STATUS = CASE WHEN ISNULL(USER1,'') = '1' THEN 'Approve'
           WHEN ISNULL(USER2,'') = '2' THEN 'Reject'
           WHEN ISNULL(USER3,'') = '3' THEN 'Pending Decision'
           ELSE 'error' END,
 USERNAME = CASE WHEN ISNULL(STATUS,'') = 'Approve' THEN (select username1 from <table> where userid = <userid>)
           WHEN ISNULL(STATUS,'') = 'Reject' THEN  (select username2 from <table> where userid = <userid>)
           WHEN ISNULL(STATUS,'') = 'Pending Decision' THEN  (select username3 from <table> where userid = <userid>)
           ELSE 'error' END

           from <table> where userid = <userid>

Ответы [ 3 ]

1 голос
/ 23 апреля 2020

Вы можете использовать «табличное выражение» для предварительного вычисления столбца. Например:

select
  *,
  -- use the pre-computed STATUS column now
from (
  SELECT *,
    <CASE-expression> as status
  from <table> where userid = <userid>
) x
1 голос
/ 23 апреля 2020

Вы не можете повторно использовать выражение, определенное в предложении select в том же предложении.

Я действительно не понимаю, зачем вам значение, возвращаемое первым выражением, чтобы вычислить второе значение, так как logi c в основном то же самое.

Вы можете просто сделать:

select
    case 
        when user1 = 1 then then 'Approve'
        when user2 = 2 then 'Reject'
        when user3 = 3 then 'Pending Decision'
        else 'error' 
    end status,
    case 
        when user1 = 1 then (select username1 from <table> where userid = <userid>)
        when user2 = 2 then (select username2 from <table> where userid = <userid>)
        when user3 = 3 then (select username3 from <table> where userid = <userid>)
    end username
from <table> where userid = <userid>

Примечания

  • isnull() не нужны, так как альтернативное значение не попадает нигде в case оператор

  • это обрабатывает user1 как число, потому что оно выглядит так - поэтому я цитировал тестовые значения в операторе case. Если это на самом деле строка, вы можете вернуть ее и добавить одинарные кавычки.

  • Я довольно подозрительно отношусь к логике c подзапросов; могут быть способы упростить это, если вы предоставите более подробную информацию о том, что они намерены делать, вместе с образцами данных и желаемыми результатами.

1 голос
/ 23 апреля 2020

Это работает, потому что @status будет обрабатываться перед именем пользователя

И вы должны использовать пользовательские переменные, вы не можете использовать имена столбцов для этого

  SELECT
  @status := (CASE WHEN COALESCE(USER1,'') = '1' THEN 'Approve'
           WHEN COALESCE(USER2,'') = '2' THEN 'Reject'
           WHEN COALESCE(USER3,'') = '3' THEN 'Pending Decision'
           ELSE 'error' END)  `STATUS` 
           ,
  CASE WHEN COALESCE(@status,'') = 'Approve' THEN (select username1 from table1 where userid = 20)
          WHEN COALESCE(@status,'') = 'Reject' THEN  (select username2 from table1 where userid = 20)
           WHEN COALESCE(@status,'') = 'Pending Decision' THEN  (select username3 from table1 where userid = 20)
           ELSE 'error' END USERNAME 

           from table1 where userid = 20
...