Выбор столбцов, которые не все являются нулевыми

#sql #sql-server #case #sql-null

#sql #sql-сервер #случай #sql-null

Вопрос:

Итак, у меня есть запрос, который выглядит следующим образом —

 select 
case when @subType = 1 or @subType = 2 then id end as Id,
case when  @subType = 3 then name end as name
case when @subType = 3 or @subType = 2 then address end as address
from 
table
 

Итак, проблема, с которой я сталкиваюсь, заключается в том, что если @subType равно 3, то столбец с именем ID будет иметь значение null. Тогда я не хочу возвращать весь этот столбец. И наоборот, если @subType равно 2, то все name будет null, поэтому мне не нужен весь этот столбец.

Комментарии:

1. Результирующий набор SELECT инструкции должен иметь постоянную форму, определенную во время компиляции. Если вы хотите возвращать разные столбцы , в зависимости от @subType , вы должны использовать несколько операторов и использовать IF .. ELSE для выбора между ними. Однако это потенциально усложнит обработку результата, поскольку теперь ваш клиент не сможет рассчитывать на присутствие всех столбцов.

2. Зачем вам вообще нужен такой запрос? В каждом случае он будет возвращать разные типы данных, что означает, что клиенту придется либо обрабатывать их все как текст, объект, динамическое или слабо типизированное значение, в зависимости от языка

3.Кстати, этот запрос не вернет значения NULL. Если subtype равно 3, вы получите name только . Ни Address то, ни ID другое не будет возвращено.

4. @PanagiotisKanavos он вернет null для идентификатора, если подтип равен 3.

5. [address] будет возвращено значение @subtype is 3 , @PanagiotisKanavos , CASE выражение case when @subType = 3 or @subType = 2 then address end as address

Ответ №1:

Единственный способ сделать это — использовать динамический SQL (как упоминает Гордон). При условии, что это запрос, а не функция, просмотр, тогда вы могли бы сделать это:

 DECLARE @subType tinyint = 3;

DECLARE @SQL nvarchar(MAX);

SET @SQL = N'SELECT '  
           STUFF(CASE WHEN @subType IN (1,2) THEN N','   NCHAR(13)   NCHAR(10)   N'       id' ELSE N'' END   
                 CASE WHEN @subType = 3 THEN N','   NCHAR(13)   NCHAR(10)   N'       [name]' ELSE N'' END   
                 CASE WHEN @subType IN (3,2) THEN N','   NCHAR(13)   NCHAR(10)   N'       [address]' ELSE N'' END, 1, 10,N'')   NCHAR(13)   NCHAR(10)  
           N'FROM YourTable;';

PRINT @SQL; --Your debugging best friend.
--EXEC sp_executesql @SQL; --Uncomment to run the statement
 

Но, если запрос поступает из уровня представления, то на самом деле это должно обрабатывать отображаемые столбцы, а не SQL Server

Если вы также передаете параметры в WHERE свой запрос, убедитесь, что вы параметрируете вызов to sp_executesql ; не вводите значения параметров в динамический оператор.

Комментарии:

1. Это именно то, что мне нужно. Большое вам спасибо.

Ответ №2:

Это слишком долго для комментария.

SQL-запрос возвращает фиксированный набор столбцов с именами и типами, определенными в SELECT . Он не может иметь переменное количество столбцов.

Чтобы делать то, что вы хотите, вам нужно будет использовать динамический SQL. Я не уверен, работает ли это в вашем контексте. Например, динамический SQL не поддерживается в пользовательских функциях SQL Server.

Комментарии:

1. пользователь может использовать двойную таблицу, затем ее можно создать на SQL server!!

2. @nikhilsugandh что бы это дало? dual это просто таблица чисел. Это не влияет на значения null