использование CASE WHEN в операторе SQL

Мне нужно отображать информацию, сравнивая данные в двух столбцах идентификаторов, в одном столбце есть «ВСЕ» и числа как идентификаторы, а в другом - только числа в качестве идентификаторов. Моя проблема в том, что я не могу сравнивать столбцы символов и чисел с числовым столбцом. Поэтому я использую CASE WHEN.

Если значение равно «ВСЕ», то в выводе отображается «ВСЕ», в противном случае отображается имя для совпадающих записей.

Вот код:

CASE
  WHEN secorg.org_id = 'ALL' THEN 'ALL'
  WHEN secorg.org_id = progmap.org_id THEN secorg.org_name
END AS org_name,

условие таково: «secorg.org_id = progmap.org_id», который основан на идентификаторе, и я должен отображать secorg.org_name, если идентификаторы совпадают.

Вот весь запрос:

SELECT distinct program_id,
                prog_name,
                case
                  when Eitc_Active_Switch = '1' then 'ON'
                  when Eitc_Active_Switch = '0'then 'OFF'
                End as Prog_Status,
                progmap.client_id,
                case
                  when secorg.org_id = 'ALL' then 'ALL'
                  --when secorg.org_id = progmap.org_id then secorg.org_name
                  else secorg.org_name
                end as org_name,
                case
                  when prog.has_post_calc_screen = 'True' then 'True'
                  Else 'False'
                End as Referal_ID,
                case
                  when progmap.program_ID IN ( 'AMC1931', 'AMCABD', 'AMCMNMI',
                                               'AMC' )
                       And sec.calwinexists_ind = '1' then 'Yes'
                  when progmap.program_ID IN ( 'AMC1931', 'AMCABD', 'AMCMNMI',
                                               'AMC' )
                       And sec.calwinexists_ind = '0'then 'No'
                  when progmap.program_ID NOT IN (
                       'AMC1931', 'AMCABD', 'AMCMNMI', 'AMC' ) then
                  'N/A'
                End as calwin_interface,
                sec.Client_name
FROM   ref_programs prog (nolock)
       LEFT OUTER JOIN ref_county_program_map progmap (nolock)
         ON progmap.program_id = prog.prog_id
            AND progmap.CLIENT_ID = prog.CLIENT_ID
       INNER join sec_clients sec (nolock)
         on sec.client_id = progmap.Client_id
       Inner join sec_organization secorg (nolock)
         on secorg.org_id = progmap.org_id  

person userstackoverflow    schedule 21.04.2011    source источник
comment
Какую ошибку вы получаете?   -  person SteAp    schedule 22.04.2011
comment
Было бы полезно узнать, какую базу данных вы используете   -  person OMG Ponies    schedule 22.04.2011
comment
Я получаю сообщение об ошибке «ВСЕ», в нем говорится, что: Преобразование не удалось при преобразовании значения varchar «ВСЕ» в тип данных int   -  person userstackoverflow    schedule 22.04.2011


Ответы (2)


Почему бы не преобразовать числовые столбцы в столбцы varchar?

Если вы используете SQL SERVER, вы можете сделать это так:

CONVERT(VARCHAR,secorg.org_id) = CONVERT(VARCHAR,progmap.org_id)

Вам нужно будет выполнить внешнее соединение для случаев, когда столбец, который является одновременно «ALL» и числом, равен «All», поскольку он не сможет выполнить внутреннее соединение с другой таблицей.

Для быстрого исправления на основе приведенного выше кода вы можете просто изменить второе предложение WHEN, чтобы оно выглядело так (опять же при условии, что вы используете MS SQL SERVER):

WHEN CONVERT(VARCHAR,secorg.org_id) = CONVERT(VARCHAR,progmap.org_id) THEN secorg.org_name

Попробуйте это как ваш запрос:

SELECT DISTINCT 
    program_id, 
    prog_name,
    CASE Eitc_Active_Switch
        WHEN '1' THEN 'ON'
        ELSE 'OFF'
    END AS Prog_Status,
    progmap.client_id,
    ISNULL(secorg.org_name,'ALL') AS org_name,
    CASE prog.has_post_calc_screen
        WHEN 'True' THEN 'True'
        ELSE 'False'
    END AS Referal_ID,
    CASE WHEN progmap.program_ID IN ('AMC1931','AMCABD','AMCMNMI','AMC') AND sec.calwinexists_ind = '1' THEN
        'Yes'
        WHEN progmap.program_ID IN ('AMC1931','AMCABD','AMCMNMI','AMC') AND sec.calwinexists_ind = '0' THEN
        'No'
        WHEN progmap.program_ID NOT IN ('AMC1931','AMCABD','AMCMNMI','AMC') THEN
        'N/A'
    END AS calwin_interface,
    sec.Client_name
FROM
    ref_programs prog (nolock)
LEFT OUTER JOIN ref_county_program_map progmap (nolock) ON progmap.program_id = prog.prog_id AND progmap.CLIENT_ID = prog.CLIENT_ID
INNER JOIN sec_clients sec (nolock) ON sec.client_id = progmap.Client_id
LEFT OUTER JOIN sec_organization secorg (nolock) ON CONVERT(VARCHAR,secorg.org_id) = CONVERT(VARCHAR,progmap.org_id)
person Ryan    schedule 21.04.2011
comment
Я разместил весь свой запрос. Пожалуйста, взгляните на это - person userstackoverflow; 22.04.2011
comment
Данные в числовом столбце и столбце «ВСЕ» собираются на основе некоторого условия. Я не могу его изменить. Мне нужно только отображать имя для совпадения идентификаторов в обоих столбцах. - person userstackoverflow; 22.04.2011
comment
да, я использую sql-сервер. это хранимая процедура, которую я пишу - person userstackoverflow; 22.04.2011
comment
Я сделал, как ты сказал. но это дает мне сообщение об ошибке Неправильный синтаксис рядом с '.' - person userstackoverflow; 22.04.2011
comment
Это дает мне это сообщение об ошибке? Ошибка преобразования при преобразовании значения varchar 'ALL' в тип данных int - person userstackoverflow; 22.04.2011
comment
как я могу получить имена типов данных всей таблицы - person userstackoverflow; 22.04.2011
comment
На самом деле я вижу проблему... вы можете полностью удалить оператор case для org_name из запроса, если вы используете это последнее внутреннее соединение в своем запросе... Я отредактировал его еще раз, попробуйте. - person Ryan; 22.04.2011
comment
Я должен искать их на основе их идентификаторов... В противном случае весь запрос неверен! - person userstackoverflow; 22.04.2011
comment
Я использовал ваш запрос... Я получаю вывод только с числовыми значениями. Я вообще не могу отображать значения "ВСЕ" - person userstackoverflow; 22.04.2011
comment
Если вы выполняете последнее внутреннее соединение, которое у вас есть в вашем запросе, то этот оператор case, который у вас был, спорный, потому что только один из столбцов, которые вы указали, имеет значение «все», поэтому внутреннее соединение удалит все записи, которые имеют ' все» в одном столбце, поскольку их нет в другом. Последнее внутреннее соединение обеспечивает соединение двух таблиц и всегда будет возвращать действительное имя org_name. - person Ryan; 22.04.2011
comment
Если вам нужны все значения, последнее соединение, которое у вас есть, должно быть внешним соединением, и мне придется добавить оператор case обратно для org_name... - person Ryan; 22.04.2011
comment
Я это понимаю. Но требование состоит в том, что он должен отображать записи, только если они имеют совпадающий идентификатор, в противном случае он должен отображать опцию «ВСЕ». - person userstackoverflow; 22.04.2011
comment
В порядке. Я могу выполнить запрос без ошибок и получить все совпадающие значения... но это большое количество записей в отправленном результате... чем то, что я раньше использовал для получения... ранее я использовал для получения 440 записей с комбинацией ВСЕ и число... теперь я получаю 20000 записей... - person userstackoverflow; 22.04.2011
comment
Я не думаю, что это должно произойти!! - person userstackoverflow; 22.04.2011
comment
сохраните свой запрос в том виде, в котором он у вас есть, но внесите эти 2 изменения... в строке 11 вашего запроса измените его на END AS org_name, а в самой последней строке вашего запроса сделайте так, чтобы он читался так... Внутреннее соединение sec_organization secorg (без блокировки) на CONVERT(VARCHAR,secorg.org_id) = CONVERT(VARCHAR,progmap.org_id) - person Ryan; 22.04.2011

Оператор case в порядке, это псевдоним поля, который должен быть плохим.

     END As org_name

Составной псевдоним, такой как secorg.org_name, не будет работать.

person Conrad Frix    schedule 22.04.2011