2013-03-20 3 views
1

У меня есть следующие данные:Подсчет конкретных значений по столбцам в SQL Server 2008 вид


ID Column1 Column2 Column3 Column4 Column5 
    001 A  C  D  A  B 
    002 A  D  A  B  A 
    003 B  K  Q  C  Q 
    004 A  K  E  E  B 

Я хочу, чтобы создать новый столбец в представлении, которое дает мне отсчет «A «s по 5 столбцам источника для каждой строки. Результат должен выглядеть следующим образом:

ID Column1 Column2 Column3 Column4 Column5 SumOfA 
    001 A  C  D  A  B  2 
    002 A  D  A  B  A  3 
    003 B  K  Q  C  Q  0 
    004 A  K  E  E  B  1 

Я видел несколько примеров здесь, но они возвращают экземпляры «А» по ​​записи - я хочу, чтобы счетчик «A» s по столбцам, а не агрегация через строки. Есть предположения?

ответ

2

For A подобная ситуация, я предпочитаю использовать C ROSS APPLY, чтобы сделать промежуточный логический UNPIVOT.

SELECT 
    * 
FROM 
    dbo.YourTable T 
    CROSS APPLY (
     SELECT Count(*) 
     FROM (VALUES (Column1), (Column2), (Column3), (Column4), (Column5)) C (Val) 
     WHERE Val = 'A' 
    ) A (Cnt) 

Это также имеет то преимущество, что может изменить какое значение вы рассчитываете только в одном месте, а не в 5 местах, и это очень легко добавить несколько столбцов, если это необходимо.

Смотреть это working in a Sql Fiddle

Однако, что вы изо всех сил, чтобы построить этот запрос показывает, что конструкция стола, вероятно, не лучше. Если сами имена столбцов содержат данные (такие как периоды времени, регионы или другие аналогичные значения), то почти наверняка проект неоптимален. Я настоятельно рекомендую вам вместо этого сохранить данные без использования - используйте одну строку и столбец за каждое значение, а новый столбец обозначает исходный столбец.

Если вы не можете изменить схему по какой-либо причине, вы могли бы рассмотреть вопрос о создании вид: (. Вы можете также использовать оператор PIVOT тоже)

CREATE VIEW dbo.YourTableUnpivoted 
SELECT 
    T.ID, 
    C.* 
FROM 
    dbo.YourTable T 
    CROSS APPLY (VALUES 
     ('Column1', Column1), 
     ('Column2', Column2), 
     ('Column3', Column3), 
     ('Column4', Column4), 
     ('Column5', Column5) 
    ) C (Col, Val); 

Затем вы можете использовать это как если он были переработаны таблицы:

SELECT 
    ID, 
    Count(*) 
FROM 
    dbo.YourTableUnpivoted 
WHERE 
    Val = 'A' 
GROUP BY 
    ID; 
+0

Спасибо! Я согласен с тем, что дизайн таблицы субоптимален, и то, что вы описали, так оно и должно быть. Проблема в том, что исходная система (REDCap) имеет только однонаправленные структуры таблицы, поэтому эти повторяющиеся значения хранятся в отдельных столбцах, поэтому я работаю с ней как есть, а не преобразовываю ее в настоящее время. –

+0

Я пробовал это, кстати, работает очень хорошо, спасибо. Я бы использовал это как решение, но первое было опубликовано первым. Я сохраню его в другой раз, я буду работать через это позже. –

+0

См. Мое обновление для еще одной идеи. Спасибо за проверку кода. – ErikE

1
SELECT 
(CASE WHEN Column1 = 'A' THEN 1 ELSE 0 END 
+ CASE WHEN Column2 = 'A' THEN 1 ELSE 0 END 
+ CASE WHEN Column3 = 'A' THEN 1 ELSE 0 END 
+ CASE WHEN Column4 = 'A' THEN 1 ELSE 0 END 
+ CASE WHEN Column5 = 'A' THEN 1 ELSE 0 END) AS SumOfA 
FROM myTable 
3

Вы можете использовать несколько CASE выражения для подсчета A значения:

select id, 
    column1, 
    column2, 
    column3, 
    column4, 
    column5, 
    case when column1 = 'A' then 1 else 0 end + 
    case when column2 = 'A' then 1 else 0 end + 
    case when column3 = 'A' then 1 else 0 end + 
    case when column4 = 'A' then 1 else 0 end + 
    case when column5 = 'A' then 1 else 0 end TotalA 
from yourtable 

См SQL Fiddle with Demo

+0

+1 для получения дополнительной информации и указания на пример sqlfiddle. – shahkalpesh

+0

@bluefeet удары :) Что я могу сказать. – DevelopmentIsMyPassion

0

Вы можете использовать CASE заявление для достижения этого:

SELECT 
    column1, column2, column3, column4, column5, 
    (CASE WHEN Column1 = 'A' THEN 1 ELSE 0 END 
    + CASE WHEN Column2 = 'A' THEN 1 ELSE 0 END 
    + CASE WHEN Column3 = 'A' THEN 1 ELSE 0 END 
    + CASE WHEN Column4 = 'A' THEN 1 ELSE 0 END 
    + CASE WHEN Column5 = 'A' THEN 1 ELSE 0 END) AS TotalSum 
FROM yourTable 
Смежные вопросы