#sql-server #tsql #sql-server-2008
#sql-server #tsql #sql-server-2008
Вопрос:
В настоящее время у меня есть оператор select, который проверяет несколько столбцов, чтобы увидеть, есть ли в них данные. если какое-либо из них равно null, то я хочу, чтобы бит был установлен в false. если ни одно из них не равно null, тогда я хочу, чтобы бит был установлен в true. вот что у меня сейчас есть:
select
cast(
case when ChangeOrderNumber is null then 0 else 1 end *
case when ClientName is null then 0 else 1 end *
case when QuoteNumber is null then 0 else 1 end *
case when ClientNumber is null then 0 else 1 end *
case when ServiceLine is null then 0 else 1 end *
case when ServiceLineCode is null then 0 else 1 end *
case when GroupLeader is null then 0 else 1 end *
case when CreatedBy is null then 0 else 1 end *
case when PTWCompletionDate is null then 0 else 1 end *
case when BudgetedHours is null then 0 else 1 end *
case when BudgetDollars is null then 0 else 1 end *
case when InternalDeadlineDate is null then 0 else 1 end *
case when ProjectDescription is null then 0 else 1 end *
case when Sales is null then 0 else 1 end *
case when Coop is null then 0 else 1 end *
case when PassThrough is null then 0 else 1 end *
case when POStatus is null then 0 else 1 end *
case when PONumber is null then 0 else 1 end as bit
)
as Flag
from t
теперь этот код работает, но он немного длинный, мне было интересно, знает ли кто-нибудь лучший способ сделать это. пожалуйста, обратите внимание, что проверяется несколько типов данных.
дополнительные сведения: этот код находится в представлении, которое просматривается в приложении для обработки заказов на изменение. прежде чем заказ на изменение может быть обработан, он должен соответствовать некоторым проверкам качества данных. это представление показывает, являются ли какие-либо из требуемых данных null.
Комментарии:
1. Давай, Дэвид … разве ты не знаешь, как это сделать: P
Ответ №1:
Просто сложите их, поскольку NULL «что-то» всегда равно NULL …
CREATE TABLE #test(column1 int,column2 varchar(4),column3 float)
INSERT #test VALUES(2,'2',2)
INSERT #test VALUES(0,'1',0)
INSERT #test VALUES(null,'1',0)
INSERT #test VALUES(1,null,0)
INSERT #test VALUES(0,'1',null)
INSERT #test VALUES(null,null,null)
SELECT CASE
WHEN column1 column2 column3 is NULL THEN 0 ELSE 1 END, *
FROM #test
из сообщения, которое я создал более 3 лет назад…
Имейте в виду, что если у вас есть символы, которые не являются числами, в которые вы должны преобразовать varchar
…
INSERT #test VALUES(0,'abc',null)
Вот преобразование, нет необходимости преобразовывать столбцы varchar
SELECT CASE WHEN CONVERT(VARCHAR(100),column1)
column2
CONVERT(VARCHAR(100),column3) is NULL THEN 0 ELSE 1 END,*
FROM #test
Комментарии:
1. Аналогично добавлению, вы также можете использовать побитовый оператор and (amp;) ‘ВЫБЕРИТЕ СЛУЧАЙ, КОГДА (4 amp; 5 amp; null) > 0, ЗАТЕМ 1, ИНАЧЕ 0 ЗАКАНЧИВАЕТСЯ’
2. как я указал в последней строке….
keep in mind that if you have characters that are not numbers that you have to convert to varchar
3. @SQLMenace, в том-то и дело, что переменные содержат нечисловые символы, поэтому при преобразовании происходит сбой
4. В этом случае преобразуйте все в varchar
5. @SQLMenace, тогда это так же долго / кроваво
Ответ №2:
Я думаю, что я мог бы использовать это решение, если кто-то не придумает лучшее, вдохновленное @Alireza:
cast(
case when (ChangeOrderNumber is null or
a.ClientName is null or
a.QuoteNumber is null or
ClientNumber is null or
ServiceLine is null or
ServiceLineCode is null or
GroupLeader is null or
CreatedBy is null or
PTWCompletionDate is null or
BudgetedHours is null or
BudgetDollars is null or
InternalDeadlineDate is null or
ProjectDescription is null or
Sales is null or
Coop is null or
PassThrough is null or
POStatus is null or
PONumber is null) then 'false' else 'true'
end as bit) as Flag
Ответ №3:
Пожалуйста, используйте IIF()
(должен быть sql server 2012 или более поздней версии) Я действительно рекомендую:
IIF(column1 is null, '0', '1')
Ответ №4:
Что насчет этого?
select not(a is null or b is null or ...)
Ответ №5:
Вы могли бы инвертировать логику.
SELECT
CASE WHEN ChangeOrderNumber IS NOT NULL
AND ClientName IS NOT NULL
AND QuoteNumber IS NOT NULL
....
THEN 1
ELSE 0
END [Flag]
FROM t
Ответ №6:
Создайте функцию HasValue, которая принимает sql_variant и возвращает бит. Затем используйте побитовое И в вашем SELECT
предложении.
CREATE FUNCTION dbo.HasValue(@value sql_variant) RETURNS bit
AS
BEGIN
RETURN (SELECT COUNT(@value))
END
GO
SELECT dbo.HasValue(ChangeOrderNumber)
amp; dbo.HasValue(ClientName)
amp; dbo.HasValue(QuoteNumber)
...
as [Flag]
FROM t
Комментарии:
1. интересно, мне придется посмотреть, какова производительность
Ответ №7:
Или это:
declare @test1 char(1)
declare @test2 char(1)
declare @outbit bit
set @test1 = NULL
set @test2 = 'some value'
set @outbit = 'True'
select @test1
select @test2
If @test1 @test2 IS NULL set @outbit = 'False'
Select @outbit
Комментарии:
1. вы тестируете только один и тот же тип данных, у моего есть несколько типов данных. добавление int к символу char завершится ошибкой, если в символе есть какие-либо нечисловые символы
Ответ №8:
Намного проще — просто используйте COALESCE
функцию, которая возвращает значение в первом ненулевом столбце.
SELECT Flag = CASE
WHEN COALESCE (column1, column2, column3, ...) IS NULL THEN 0
ELSE 1
END
FROM MyTable