Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Dynamic SQL - значения поля в качестве условия CASE  [new]
Andrey3000
Member

Откуда:
Сообщений: 49
Добрый день!

Есть вот такая таблица:

EntityIDValueBadPoorFineExcellent
40.038222845Value <= 0.1Value >= 0 AND Value < 0.3Value >= 0.3 AND Value < 0.4 OR Value >= 0.6Value >= 0.4 AND Value < 0.6


Какую конструкцию я очень сильно хочу выполнить:

DECLARE @sql AS VARCHAR(MAX)
DECLARE @ColumnBad AS VARCHAR(MAX)
DECLARE @ColumnPoor AS VARCHAR(MAX)
DECLARE @ColumnFine AS VARCHAR(MAX)
DECLARE @ColumnExcellent AS VARCHAR(MAX)

SELECT @ColumnBad =  Bad FROM Table
SELECT @ColumnPoor = Poor FROM Table
SELECT @ColumnFine = Fine FROM Table
SELECT @ColumnExcellent = Excellent FROM Table

SELECT @sql = '
SELECT ID
      ,CASE 
		   WHEN ' + @ColumnBad + ' THEN 2
	  END Result
FROM Table
'

EXECUTE (@sql)


То есть мне нужно в динамический запрос передать данные из поля BAD и выполнить CASE

Почему хочу выполнить именно так - условий очень много и они постоянно меняются

Нет ли у кого на примете вариантов решения (перечитал много всего, но где-то принципиальная ошибка)

Спасибо за помощь!
2 ноя 17, 16:06    [20922441]     Ответить | Цитировать Сообщить модератору
 Re: Dynamic SQL - значения поля в качестве условия CASE  [new]
iap
Member

Откуда: Москва
Сообщений: 46981
SELECT @sql = N'
SELECT ID
      ,CASE 
		   WHEN ' + Bad + ' THEN 2
	  END Result
FROM [Table] WHERE EntityID=4'
FROM [Table]
WHERE EntityID=4;

EXECUTE(@sql);
Вообще непонятно, что ожидаете получить, запихивая в скалярную переменную все значения Bad из таблицы [Table].
Я вписал в запрос ограничение по EntityID вместо вас...
2 ноя 17, 16:16    [20922475]     Ответить | Цитировать Сообщить модератору
 Re: Dynamic SQL - значения поля в качестве условия CASE  [new]
Andrey3000
Member

Откуда:
Сообщений: 49
iap,

Спасибо, в чем проблема понятна.
А нет вариантов применить условия применительно ко всей таблице (представим что строчек много)? (не детализируя) - то есть для каждой строчки вынуть значения для Case (именно из этой строчки)
2 ноя 17, 16:35    [20922515]     Ответить | Цитировать Сообщить модератору
 Re: Dynamic SQL - значения поля в качестве условия CASE  [new]
Ролг Хупин
Member

Откуда: Чебаркуль
Сообщений: 3708
Andrey3000
iap,

Спасибо, в чем проблема понятна.
А нет вариантов применить условия применительно ко всей таблице (представим что строчек много)? (не детализируя) - то есть для каждой строчки вынуть значения для Case (именно из этой строчки)


сколько записей в таблице?

1. сгенерируйте строку динамического запроса в одну строку и выполните
2. сгенерируйте в эту же или другую табллицу в каждое поле запрос и затем пройдитесь по ней и выполните
3. ....
2 ноя 17, 17:07    [20922586]     Ответить | Цитировать Сообщить модератору
 Re: Dynamic SQL - значения поля в качестве условия CASE  [new]
HTMLfile,
Guest
просто, пусть тут полежит :)

declare @c table(Value float, Bad varchar(100), Poor varchar(100), Fine varchar(100), Excellent varchar(100))

insert into @c
values
(0.038222845,'Value <= 0.1', 'Value >= 0 AND Value < 0.3', 'Value >= 0.3 AND Value < 0.4 OR Value >= 0.6', 'Value >= 0.4 AND Value < 0.6'),
(0.56,'Value <= 0.1', 'Value >= 0 AND Value < 0.3', 'Value >= 0.3 AND Value < 0.4 OR Value >= 0.6', 'Value >= 0.4 AND Value < 0.6'),
(0.3,'Value <= 0.1', 'Value >= 0 AND Value < 0.3', 'Value >= 0.3 AND Value < 0.4 OR Value >= 0.6', 'Value >= 0.4 AND Value < 0.6'),
(0.457,'Value >= 0.4 AND Value < 0.6', 'Value >= 0 AND Value < 0.3', 'Value >= 0.3 AND Value < 0.4 OR Value >= 0.6', 'Value <= 0.1')

--	
select 
	Value 
	,result		=[dbo].[fnEval](a.x) 
from @c 
outer apply (select 
		x = replace(replace(replace('('+Bad+') ? "Bad" : ('+Poor+') ? "Poor" : ('+Fine+') ? "Fine" : ('+Excellent+') ? "Excellent" : "XZ"', ' AND ', ' && '), ' OR ', ' || '),'Value',Value)
	) a


Valueresult
0,038222845Bad
0,56Excellent
0,3Fine
0,457Bad


+
create FUNCTION [dbo].[fnEval]
(
	@txt		varchar(4000)		
)
RETURNS varchar(8000) 
as
begin
	declare @Result varchar(8000)
	declare @object int, @object2 int
	declare @hr int

	set @txt='<body><script>document.write(' + @txt + ');</script></body>'

	exec @hr=sp_OACreate 'HTMLfile', @object out
	exec @hr=sp_OAMethod @object, 'write', null, @txt
	exec @hr=sp_OAGetProperty @object, 'body', @object2 out 
	exec @hr=sp_OAGetProperty @object2, 'innerText', @Result out 

	exec @hr=sp_OADestroy @object2
	exec @hr=sp_OADestroy @object
	
	return @Result 
end
2 ноя 17, 17:45    [20922676]     Ответить | Цитировать Сообщить модератору
 Re: Dynamic SQL - значения поля в качестве условия CASE  [new]
Andrey3000
Member

Откуда:
Сообщений: 49
HTMLfile

Что-то вне предела моего понимания.
Не могу выполнить, permission
2 ноя 17, 18:23    [20922763]     Ответить | Цитировать Сообщить модератору
 Re: Dynamic SQL - значения поля в качестве условия CASE  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1369
Andrey3000,

потому что чтобы использовать процедуры sp_OA необходимо быть в роли sysadmin
2 ноя 17, 18:35    [20922797]     Ответить | Цитировать Сообщить модератору
 Re: Dynamic SQL - значения поля в качестве условия CASE  [new]
Andrey3000
Member

Откуда:
Сообщений: 49
felix_ff,
Вы это специально! Не админ да (
Мучаюсь вот с генерацией строки
2 ноя 17, 21:54    [20923202]     Ответить | Цитировать Сообщить модератору
 Re: Dynamic SQL - значения поля в качестве условия CASE  [new]
HTMLfile,
Guest
Andrey3000
Мучаюсь вот с генерацией строки
что-то типа такого, имхо

declare @SQL varchar(max)=''

create table ##c (id int, Value float, Bad varchar(100), Poor varchar(100), Fine varchar(100), Excellent varchar(100))

insert into ##c
values
(1, 0.038222845,'Value <= 0.1', 'Value >= 0 AND Value < 0.3', 'Value >= 0.3 AND Value < 0.4 OR Value >= 0.6', 'Value >= 0.4 AND Value < 0.6'),
(2, 0.56,'Value <= 0.1', 'Value >= 0 AND Value < 0.3', 'Value >= 0.3 AND Value < 0.4 OR Value >= 0.6', 'Value >= 0.4 AND Value < 0.6'),
(3, 0.3,'Value <= 0.1', 'Value >= 0 AND Value < 0.3', 'Value >= 0.3 AND Value < 0.4 OR Value >= 0.6', 'Value >= 0.4 AND Value < 0.6'),
(4, 0.457,'Value >= 0.4 AND Value < 0.6', 'Value >= 0 AND Value < 0.3', 'Value >= 0.3 AND Value < 0.4 OR Value >= 0.6', 'Value <= 0.1')


select 
@SQL=@SQL+case when row_number()over(order by id)>1 then 'union all'+char(13) else '' end+
	'select
		id  
		,Value	='+cast(Value as varchar)+'
		,Result	=case 
					when '+replace(Bad,'Value',Value)+' then ''Bad''
					when '+replace(Poor,'Value',Value)+' then ''Poor''
					when '+replace(Fine,'Value',Value)+' then ''Fine''
					when '+replace(Excellent,'Value',Value)+' then ''Excellent''
				end
from ##c
where id='+cast(id as varchar)+char(13)
from ##c
order by id 

print @SQL
exec(@SQL)

drop table ##c


idValueResult
10.0382228Bad
20.5600000Excellent
30.3000000Fine
40.4570000Bad
3 ноя 17, 11:22    [20924172]     Ответить | Цитировать Сообщить модератору
 Re: Dynamic SQL - значения поля в качестве условия CASE  [new]
Andrey3000
Member

Откуда:
Сообщений: 49
HTMLfile,
Да!
надо смотреть, но это нагляднее то чего я накрутил!
Не знаю вот как связаться с вами к сожалению (есть такая возможность?)
3 ноя 17, 12:23    [20924449]     Ответить | Цитировать Сообщить модератору
 Re: Dynamic SQL - значения поля в качестве условия CASE  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7768
Andrey3000,

это через ...опу

создайте таблицу

f1fromtomore
badnull0.1null
poor00.3null
fine0.30.4null
finenullnull0.6
excellent0.40.4null


и используйте ее для объединения с таблицей значений, которую требуется оценить.
3 ноя 17, 13:19    [20924696]     Ответить | Цитировать Сообщить модератору
 Re: Dynamic SQL - значения поля в качестве условия CASE  [new]
Руслан Дамирович
Member

Откуда: Резиновая нерезиновая
Сообщений: 940
IF OBJECT_ID( 'tempdb..#table' ) IS NOT NULL
  DROP TABLE #table
;
CREATE TABLE #table (
  EntityID INT,
  Value FLOAT )
INSERT INTO
  #table
VALUES (
  4,
  0.038222845 )
;
IF OBJECT_ID( 'tempdb..#groups' ) IS NOT NULL
  DROP TABLE #groups
;
CREATE TABLE #groups (
  [type] VARCHAR(100),
  [check] VARCHAR(MAX) )
INSERT INTO
  #groups
VALUES 
  ( 'Bad', '[Value] <= 0.1' ),
  ( 'Poor', '[Value] >= 0 AND [Value] < 0.3' ),
  ( 'Fine', '[Value] >= 0.3 AND [Value] < 0.4 OR [Value] >= 0.6' ),
  ( 'Excellent', '[Value] >= 0.4 AND [Value] < 0.6' )

DECLARE @case VARCHAR(MAX) = STUFF( ( 
  SELECT 
    'WHEN ' + [check] + ' THEN ' + QUOTENAME( [type], '''' ) + CHAR(13)
  FROM
    #groups
  FOR XML
    PATH( '' ), TYPE).value('.[1]',
 'VARCHAR(MAX)'), 1, 0, '' )
;
PRINT @case
;
DECLARE @tsql VARCHAR(MAX) = '
SELECT
  *,
  [result] = CASE
    ' + @case + '
  END
FROM
  #table'
;
PRINT @tsql
;
3 ноя 17, 15:22    [20925222]     Ответить | Цитировать Сообщить модератору
 Re: Dynamic SQL - значения поля в качестве условия CASE  [new]
Руслан Дамирович
Member

Откуда: Резиновая нерезиновая
Сообщений: 940
Ну а я бы сделал так.
+
IF OBJECT_ID( 'tempdb..#table' ) IS NOT NULL
  DROP TABLE #table
;
CREATE TABLE #table (
  [EntityID] INT,
  [Value] FLOAT )
;
INSERT INTO
  #table
VALUES 
  ( 1, 0.0382228 ),
  ( 2, 0.5600000 ),
  ( 3, 0.3000000 ),
  ( 4, 0.4570000 )
;
IF OBJECT_ID( 'tempdb..#groups' ) IS NOT NULL
  DROP TABLE #groups
;
CREATE TABLE #groups (
  [result] VARCHAR(100),
  [threshold] FLOAT,
  [inclusive] BIT )
;
INSERT INTO
  #groups
VALUES 
  ( 'Bad', 0.1, 1 ),
  ( 'Poor', 0.3, 0 ),
  ( 'Fine', 0.4, 0 ),
  ( 'Excellent', 0.6, 0 ),
  ( 'Fine', NULL, 1 )
;
DECLARE @case VARCHAR(MAX) = STUFF( ( 
  SELECT 
    CASE 
      WHEN [threshold] IS NULL THEN 'ELSE '
      ELSE ISNULL( 'WHEN [value] <' + ( CASE WHEN [inclusive] = 1 THEN '=' ELSE '' END + CONVERT( VARCHAR(MAX), [threshold] ) ) + ' THEN ', '' )
    END + QUOTENAME( [result], '''' ) + CHAR(13)
  FROM
    #groups
  ORDER BY
    CASE WHEN [threshold] IS NULL THEN 1 ELSE 0 END,
    [threshold]
  FOR XML
    PATH( '' ), TYPE).value('.[1]',
 'VARCHAR(MAX)'), 1, 0, '' )
;
--PRINT @case
;
DECLARE @tsql NVARCHAR(MAX) = N'
SELECT
  *,
  [result] = CASE
    ' + @case + N'
  END
FROM
  #table'
;
--PRINT @tsql
;
EXEC sp_executesql @tsql

3 ноя 17, 15:42    [20925281]     Ответить | Цитировать Сообщить модератору
 Re: Dynamic SQL - значения поля в качестве условия CASE  [new]
Andrey3000
Member

Откуда:
Сообщений: 49
Руслан Дамирович,

Добрый день! Спасибо!
Стану пробовать все варианты.
8 ноя 17, 12:04    [20935849]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить