2010-07-15 2 views
0

У меня есть оператор SQL Select, где мне нужно вернуть определенные значения в зависимости от условия. Мне нужно каждый раз возвращать несколько значений, но мое понимание утверждения Case заключается в том, что вы можете вернуть только одно значение для каждого случая.SQL Server - настройка нескольких значений в заявлении о случае?

Я обойду это с помощью заявлений UNION на данный момент, но все это выглядит немного громоздким - есть ли лучший способ сделать это? В принципе, у меня есть набор подсказок, каждый из которых имеет ответ «Да», «Нет» или «В будущем» (у меня на самом деле больше ответов, но я просто использую 3 для примера, чтобы он был коротким!) - Мне нужно создать столбец для каждого типа ответа, с 1 в качестве значения для соответствующего ответа и 0 для всех остальных. Это, вероятно, яснее понять, если вы посмотрите на SQL ...

My (упрощенный) запрос выглядит следующим образом:

SELECT branch, 
     promptType, 
     response, 
     1 AS 'Yes', 
     0 AS 'No', 
     0 AS 'Not Discussed' 
FROM prompts 
WHERE response = 'Y' 

UNION 

SELECT branch, 
     promptType, 
     response, 
     0 AS 'Yes', 
     1 AS 'No', 
     0 AS 'Not Discussed' 
FROM prompts 
WHERE response = 'N' 

UNION 

SELECT branch, 
     promptType, 
     response, 
     0 AS 'Yes', 
     0 AS 'No', 
     1 AS 'Not Discussed' 
FROM prompts 
WHERE response = 'D' 

ответ

3

Вы считали создание таблицы декодирования для ответов и присоединение к ней?

Например, это создаст таблицу для декодирования ответов:

CREATE TABLE decoder (response CHAR(1), [Yes] BIT, [No] BIT, [Not Discussed] BIT) 
INSERT INTO decoder VALUES ('Y', 1, 0, 0) 
INSERT INTO decoder VALUES ('N', 0, 1, 0) 
INSERT INTO decoder VALUES ('D', 0, 0, 1) 

... и тогда вы могли бы присоединиться к нему, чтобы получить аналогичный (? То же самое) результаты, как вы получаете с вашим СОЮЗ:

SELECT 
    prompts.branch, 
    prompts.prompttype, 
    prompts.response, 
    decoder.yes, 
    decoder.no, 
    decoder.[Not Discussed] 
FROM 
    prompts INNER JOIN decoder ON prompts.response = decoder.response 

Возможно, стоит подойти к рассмотрению; это более реляционное решение, чем ваш союз, и, вероятно, легче поддерживать.

+0

Интересно, я отдам! Не подумал об этом, спасибо :-) – TabbyCool

+0

Принимается в качестве наилучшего ответа, полученный запрос гораздо более ремонтоприемным, чем тот, который у меня был изначально. – TabbyCool

4

Что-то вроде ...

SELECT branch, 
     prompttype, 
     CASE WHEN response = 'Y' THEN 'Yes' 
      WHEN response = 'N' THEN 'No' 
      WHEN response = 'D' THEN 'Not Discussed' 
    FROM prompts; 

может быть то, что вы после.

После ваш комментарий, возможно ...

SELECT branch, 
     prompttype, 
     CASE WHEN response = 'Y' THEN 1 ELSE 0 AS Yes, 
     CASE WHEN response = 'N' THEN 1 ELSE 0 AS No, 
     CASE WHEN response = 'D' THEN 1 ELSE 0 AS Not_Discussed 
    FROM prompts; 

может это сделать.

+0

Мне нужно вернуть все 3 ответа каждый раз, как раз с значение 0 или 1. Таким образом, значения подсказок («Да», «Нет», «Не обсуждались») на самом деле были заголовками столбцов, и каждая запись имела бы 0 или 1 в каждом поле. Результат, который я получаю из инструкции UNION в моем исходном сообщении, на самом деле является правильным выходом, я просто подумал, что может быть лучший способ его создания. – TabbyCool

+0

Ах. Понимаю. Я подумаю об этом чуть позже. –

+0

Спасибо :-) По существу, мне нужно уметь устанавливать значения для столбцов «Да», «Нет» и «Не обсуждать» для каждой строки из оператора Case, но я не уверен, что это возможно , Может ли это быть сделано с помощью оператора If? Если нет, то Союз просто должен будет сделать это, он просто чувствует себя как много дублирования. – TabbyCool

0
SELECT branch, 
     prompttype, 
    response, 
     CASE WHEN response = 'Y' THEN 1 ELSE 0 END AS Yes, 
     CASE WHEN response = 'N' THEN 1 ELSE 0 END AS [No], 
     CASE WHEN response = 'D' THEN 1 ELSE 0 END AS Not_Discussed 
    FROM prompts; 
+0

Это то же самое, что и ответ Брайана - он не дает требуемого выхода. – TabbyCool

0

Если предложенный CASE заявление ваш возвращается несколько значений в одном столбце, что бы тип данных будет: массив, список, таблица, документ XML, бизнес-объект, и т.д.? Для действительно реляционной системы управления базами данных (TRDBMS) ответ будет переменной отношения. Но мы говорим о SQL Server, здесь.

Я думаю, что ответ, который вы ищете, это то, что типы данных SQL Server являются скалярными, а не многозначными.

+0

Мне не нужны несколько значений в одном столбце, я хочу вернуть несколько столбцов, но их значения заданы в аргументе case, чтобы результат был таким же, как и исходный. – TabbyCool

1

Нужно добавить группировку, я думаю. Я сделал это с ежеквартальными прогнозами. Если у Вас есть уникальный идентификатор для каждого ответа, было бы что-то подобное (в противном случае он будет выбрать максимальное для всей ветви/prompttype/ответ):

SELECT uniqueID, 
    branch, 
    prompttype, 
    response, 
    MAX(CASE WHEN response = 'Y' THEN 1 ELSE 0 END) AS Yes, 
    MAX(CASE WHEN response = 'N' THEN 1 ELSE 0 END) AS [No], 
    MAX(CASE WHEN response = 'D' THEN 1 ELSE 0 END) AS Not_Discussed 
FROM prompts 

GROUP BY uniqueID, 
    branch, 
    prompttype, 
    response; 
Смежные вопросы