Случай, когда пункт, чтобы найти строку в параметре - PullRequest
0 голосов
/ 31 октября 2018

В моей базе данных есть таблица tblCustomer, которая имеет 8 логических полей (MS01, MS02 ... MS08) Используя отчет SSRS, у меня есть раскрывающийся список параметров с несколькими значениями, который позволяет выбрать каждое из 10 значений Поэтому, если я выберу MS01 и MS05 из списка, параметр @idSite будет равен «MS01», «MS05»

.

'- 1' = True

Я хочу выбрать все записи из tblCustomer, где выбранные значения параметров имеют значение true

select idCustomer, MS01, MS02,MS03, MS04,MS05,MS06,MS07,MS08 from tblCustomer

WHERE     (tblCustomer.CustomerYN = '-1')
AND
CASE 
WHEN  @idSite like '%MS01%' THEN  tblCustomer.MS01=-1 
WHEN  @idSite like '%MS02%' THEN  tblCustomer.MS02=-1
WHEN  @idSite like '%MS03%' THEN  tblCustomer.MS03=-1
END as MailShot

Я также пытался использовать, когда строка была "в" pareameter

select idCustomer, MS01, MS02,MS03, MS04,MS05,MS06,MS07,MS08 from 
tblCustomer

WHERE     (tblCustomer.CustomerYN = '-1')
AND
CASE 
WHEN  'MS01' in @idSite THEN  tblCustomer.MS01=-1 
WHEN  'MS02' in @idSite THEN  tblCustomer.MS02=-1

END as MailShot

Я думал, что был близок к вышесказанному, но не радости. Кто-нибудь может указать мне правильное направление?

EDIT

@ idSite - это раскрывающийся список многозначных параметров SSRS. Он принимает значение idMailshot из таблицы ниже на основе раздела из выпадающего списка

idMailShot  Location
MS01    Location1   
MS02    Location2     
MS03    Location3 
MS04    Location4  
MS05    Location5  
MS06    Location6     
MS07    Location7   
MS08    Location8   
MS09    Location9

Так что, если я выбираю Location1 & Location 2 из выпадающего списка, «MS01, MS02» должен быть передан как @idSite Я хочу

select idCustomer from tblCustomer where
tblCustomer.MS01 =-1 AND tblCustomer.MS02=-1

Ответы [ 3 ]

0 голосов
/ 31 октября 2018

Нет способа сохранить несколько значений в переменных Sql Server, например: DECLARE @idSite ='MS01','MS02','MS03';

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

declare @idSites table
(
  idSite varchar(100)
)
insert into @idSites (idSite) 
select COLUMN_NAME from Information_schema.Columns 
where TABLE_NAME = 'Table Name' and TABLE_CATALOG = 'Database Name'

Если вы получаете строку, подобную этой "MS01,MS02,MS03" затем вам нужно написать функцию для генерации таблицы на основе comma разделенных значений, например:

CREATE FUNCTION splitstring ( @stringToSplit VARCHAR(8000) )
    RETURNS
        @returnList TABLE ([Param] [nvarchar] (500))
AS
BEGIN

    DECLARE @name NVARCHAR(255)
    DECLARE @pos INT

    WHILE CHARINDEX(',', @stringToSplit) > 0
    BEGIN
        SELECT @pos  = CHARINDEX(',', @stringToSplit) 
        SELECT @name = SUBSTRING(@stringToSplit, 1, @pos-1)

        INSERT INTO @returnList
        SELECT @name

        SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)-@pos)
    END
    INSERT INTO @returnList
    SELECT @stringToSplit
    RETURN
END

Тогда просто используйте это так:

declare @StringVariable varchar(255) = "MS01,MS02,MS03";
Select [param] from splitstring(@StringVariable)

Также ваше предложение WHERE не имеет особого смысла. Я написал тестовую среду ниже, пожалуйста, посмотрите, как я поддерживал там положение WHERE.

Ниже приведено решение с предполагаемыми данными, вы можете скопировать, вставить его в SQL Server и выполнить. Надеюсь, что это поможет вам достичь желаемого требования:).

--Declaring table with multi values
declare @idSites table
(
    idSite varchar(100)
)
insert into @idSites values ('MS01')
insert into @idSites values ('MS02')
insert into @idSites values ('MS03')

--Assuming a table with columns and values added in below CTE
;with cte as (
select 
-1 as MS01
,2 as MS02
,-1 as MS03
,-1 as CustomerYN
union all
Select 
 2 as MS01
,-1 as MS02
,0 as MS03
,0 as CustomerYN
)
--Finally The query part to fetch the data as per understood from your question.
select 
*
from cte
where cte.CustomerYN = -1
   AND(
        (cte.MS01 =  -1 AND 'MS01' = (Select idSite from @idSites where idSite = 'MS01'))
        OR (cte.MS02 =  -1 AND 'MS02' = (Select idSite from @idSites where idSite = 'MS02'))
        OR (cte.MS03 =  -1 AND 'MS03' = (Select idSite from @idSites where idSite = 'MS03'))
      )
0 голосов
/ 01 ноября 2018

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

DECLARE @idSite ='MS01','MS02','MS03';

Ваш альтернативный вариант - создать таблицу поиска на лету, используя CTE, а затем сбросить данные во временную таблицу в начале процесса создания отчета. Который сделает комбо из 10 значений и сохранит их. А затем вы используете эту временную таблицу на лету в своем предложении фильтра. Имейте в виду условие «соединения» (т. Е. Столбцы, к которым вы будете присоединяться к этой временной таблице из основной таблицы).

0 голосов
/ 31 октября 2018

Ваш WHERE не имеет смысла:

WHERE     (tblCustomer.CustomerYN = '-1')
AND
CASE 
WHEN  @idSite like '%MS01%' THEN  tblCustomer.MS01=-1 
WHEN  @idSite like '%MS02%' THEN  tblCustomer.MS02=-1
WHEN  @idSite like '%MS03%' THEN  tblCustomer.MS03=-1
END as MailShot

Ваше CASE выражение в целом не является логическим выражением, оно имеет логические выражения внутри THEN; CASE возвращает скалярное значение, а не логическое значение. Вы также добавили псевдоним CASE в свой WHERE. Вы не используете псевдонимы в вашем WHERE.

Вместо того, чтобы использовать выражение CASE (которое сделает ваш запрос не SARGable), вы бы намного лучше использовали логическую логику:

WHERE tblCustomer.CustomerYN = -1 -- -1 is a int, pass it as one
  AND ((tblCustomer.MS01 = -1 AND @idSite like '%MS01%')
   OR  (tblCustomer.MS02 = -1 AND @idSite like '%MS02%')
   OR  (tblCustomer.MS03 = -1 AND @idSite like '%MS03%'))

Обратите внимание, что если вы используете выражение CASE внутри WHERE (хотя, как я уже говорил выше, это может привести к тому, что оно не будет SARGable), вам нужно вернуть скалярное значение и создать логическое выражение. В качестве простого примера:

WHERE CASE @SomeID WHEN 1 THEN T.ColumnA
                   WHEN 2 THEN T.ColumnB
                   ELSE T.ColumnC
      END = 'Some Value'

Обратите внимание, что выражение CASE возвращает скалярное значение (значение ColumnA, ColumnB или ColumnC), а затем это скалярное значение сравнивается с литеральной строкой 'Some Value' , Ваше логическое выражение не входит в THEN, оно выходит за пределы CASE выражения.

...