2016-12-20 2 views
0

Мне нужно сделать заявление о делах.Как использовать оператор CASE в инструкции SELECT COUNT?

В зависимости от того, какое значение переменных, то необходимо выбрать правильный столбец из таблицы

StartDate и EndDate различные переменные.

Существует переменная i, созданная под названием Region, которая должна определять, в каком столбце выбирается запрос.

EDIT: Регион может быть «EW» для Англии и Уэльса, «SC» для Шотландии или «NI» для Северной Ирландии. Если EW он должен выбрать столбец 1, SC для столбца 2, NI для колонки 3

SELECT 
COUNT(COLUMN1) 
FROM bankholidays 
WHERE COLUMN1 BETWEEN @StartDate AND @EndDate) 
+0

Это означает, что вы хотите, чтобы выбрать столбец динамически? – Susang

+1

Просьба предоставить данные образца и ожидаемые данные – Viki888

+1

Столбец, на который вы рассчитываете; то есть есть нулевые значения, о которых вы беспокоитесь, или 'count (*)' или 'count (1)' (функционально идентичные) в порядке? В качестве альтернативы, это колонка в вашем заявлении WHERE, которое вас интересует? – JohnLBevan

ответ

0
SELECT CASE 
WHEN @Region = 'EW' THEN columnName 
WHEN @Region = 'SC' THEN columnName 
WHEN @Region = 'NI' THEN columnName 
END AS newColumnName FROM bankholidaysT 

Попробуйте что-то вроде этого

2

Предполагая, что вы хотите, чтобы подсчитать количество записей, для которых Column1 находится между начальной и конечной датой, то должно работать:

SELECT SUM(CASE WHEN COLUMN1 BETWEEN @StartDate AND @EndDate 
      THEN 1 ELSE 0 END) AS tally 
FROM bankholidays 

Такой подход называется условной агрегации, и часто вы будете использовать пункт GROUP BY.

Update:

Чтобы справиться с вашей @Region переменным, запрос может выглядеть следующим образом:

SELECT CASE WHEN @Region = 'val1' THEN COLUMN1 
      WHEN @Region = 'val2' THEN COLUMN2 
      WHEN @Region = 'val3' THEN COLUMN3 
     END AS new_column 
FROM bankholidays 

Обратите внимание, что я не пытался совместить это с первым запросом, так как он будет смешиваться агрегатом функции с неагрегатными терминами, и это может не иметь смысла.

+0

Моя другая переменная @Region, она может содержать 3 разных значения. Как это использовать, чтобы выбрать столбец 1, столбец 2 или столбец 3? –

0

Если вы хотите динамически подсчитать количество записей, где заданное значение столбца между двумя датами, с помощью динамического запроса:

DECLARE @column NVARCHAR(MAX) 
DECLARE @sql NVARCHAR(MAX) 

SET @column = 'COLUMN1' --Set your desired column here 
SET @sql = 'SELECT COUNT(*) FROM bankholidays WHERE ' + @column + ' BETWEEN ''' + CONVERT(NVARCHAR,@StartDate,121) + ''' AND ''' + CONVERT(NVARCHAR,@EndDate,121) + '''' 

EXEC @sql 
+0

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

+0

Я не говорю, что вы ошибаетесь, но из интереса - почему? – 3N1GM4

+0

Потому что его трудно поддерживать, особенно когда запрос растет с течением времени. У меня были кошмары с динамическим SQL, который не должен был быть там. Вы также не получаете intellisense, который помогает, когда у вас есть длинные имена объектов или не может запомнить, какой параметр входит в функцию. Кто хочет потратить 15-20 минут, распутывая иногда динамичный беспорядок, просто чтобы немного поменять его? Если вы можете сделать это без, сделайте это без. Оставьте динамическое построение SQL для ORM или используйте синонимы или просто ... что-то. – Charleh

0

TRY ЭТО ЕСЛИ вы хотите count и проверьте столбец динамически

DECLARE @sql VARCHAR(500), 
    @Region VARCHAR(100) = 'COLUMN2', --It can be Column1, Column2..... 
    @StartDate DATETIME = '2016-04-10', 
    @EndDate DATETIME = '2016-04-15' 

SET @sql = ' 
    SELECT 
    COUNT(' + @Region + ') 
    FROM bankholidays 
    WHERE ' + @Region + ' BETWEEN ''' + CAST(@StartDate AS VARCHAR) + ''' AND ''' + CAST(@EndDate AS VARCHAR) + '''' 

EXEC (@SQL) 

--query выполняется, как показано ниже

SELECT 
COUNT(COLUMN2)--It can be Column1, Column2..... 
FROM bankholidays 
WHERE COLUMN2 BETWEEN 'Apr 10 2016 12:00AM' AND 'Apr 15 2016 12:00AM' 
1

1) Если вас не интересует исключение нулей из вашего счета, вам не нужно указывать имя столбца в вашем заявлении COUNT. т.е.

select count(Column1) 

даст тот же результат, как

select count(1) 

Или

select count(*) 

Пока column1 не имеет нулевых значений. Если столбец1 содержит нули, они не учитываются (поэтому, если есть 10 записей, из которых 3 имеют нулевые значения в столбце 1, вы получите результат 7, используя count(column1) или количество 10, используя другие методы.

Я упоминаю это сначала, как будто вы заботитесь о нулях, а затем меняя, какой столбец используется здесь, имеет смысл; если вы этого не сделаете, перейдите с более простой логикой только count(1)/counnt(*).

Все, что сказал, вот как изменить этот столбец:

select count(
    case @Region 
     when 1 then Column1 
     when 2 then Column2 
     else Column3 
    end 
) 

2) Если вы хотите изменить столбец, используемый в вашей WHERE заявлении, есть несколько подходов:

SELECT COUNT(1) 
FROM bankholidays 
WHERE case @Region 
    when 1 then Column1 
    when 2 then Column2 
    else Column3   
end BETWEEN @StartDate AND @EndDate 

или

SELECT COUNT(1) 
FROM bankholidays 
WHERE (@Region = 1 and Column1 BETWEEN @StartDate AND @EndDate) 
or (@Region = 2 and Column2 BETWEEN @StartDate AND @EndDate 
or (@Region not in (1,2) and Column3 BETWEEN @StartDate AND @EndDate 

Лично я предпочитаю первый стиль выше, так как он требует меньше повторов; однако второй стиль предлагает возможность использовать разные начальные & даты окончания для разных столбцов или добавить в другую логику, так что по-прежнему стоит осознавать.

+0

Если вас интересует 'count (1)' vs 'count (*)' piece, здесь есть обсуждения: http://stackoverflow.com/questions/1221559/count-vs-count1. 'Count (*)' чаще всего распознается, но я предпочитаю 'count (1)', поскольку я считаю его более значимым, а также больше соответствует другим операторам агрегата (например, 'sum (1)') – JohnLBevan

+1

Это тоже помогло мне , благодаря! –

-1
declare @Region varchar(10) 
set @Region='EW' 

SELECT 
COUNT(*) OVER(PARTITION BY 1) as TotalRows, 
Case 
    when @Region ='EW' THEN Column1 
    when @Region ='SC' THEN Column2 
    when @Region ='NI' THEN Column3 
end as [NewColumn] 
FROM [BankHolidays] 
WHERE COLUMN1 BETWEEN @StartDate AND @EndDate 
+0

Я думаю, что вопрос также требует, чтобы столбец в разделе 'WHERE' также был динамически задан в зависимости от значения' @ Region'. – 3N1GM4

Смежные вопросы