0

SQL에서 이와 같은 작업을 수행 할 수 있습니까? 이는 SQL Server Report Builder에서 작성된 보고서를 기반으로합니다. 사용자는 여러 텍스트 값을 단일 보고서 매개 변수로 지정할 수 있습니다. 보고서에 대한 쿼리는 사용자가 선택한 모든 값을 가져 와서 단일 변수에 저장합니다. 사용자가 지정한 모든 값에 대한 연관이있는 레코드 만 반환하는 쿼리가 필요합니다.SQL Server 2008 : 다른 값 집합에 여러 값을 설정하는 경우

-- Assume there's a table of Elements with thousands of entries. 
-- Now we declare a list of properties for those Elements to be associated with. 

create table #masterTable (
    ElementId int, Text varchar(10) 
) 

insert into #masterTable (ElementId, Text) values (1, 'Red'); 
insert into #masterTable (ElementId, Text) values (1, 'Coarse'); 
insert into #masterTable (ElementId, Text) values (1, 'Dense'); 
insert into #masterTable (ElementId, Text) values (2, 'Red'); 
insert into #masterTable (ElementId, Text) values (2, 'Smooth'); 
insert into #masterTable (ElementId, Text) values (2, 'Hollow'); 

-- Element 1 is Red, Coarse, and Dense. Element 2 is Red, Smooth, and Hollow. 
-- The real table is actually much much larger than this; this is just an example. 

-- This is me trying to replicate how SQL Server Report Builder treats 
-- report parameters in its queries. The user selects one, some, all, 
-- or no properties from a list. The written query treats the user's 
-- selections as a single variable called @Properties. 
-- Example scenario 1: User only wants to see Elements that are BOTH Red and Dense. 
select e.* 
from Elements e 
where (@Properties) --ideally a set containing only Red and Dense 
in 
(select Text from #masterTable where ElementId = e.Id) --ideally a set containing only Red, Coarse, and Dense 
--Both Red and Dense are within Element 1's properties (Red, Coarse, Dense), so Element 1 gets returned, but not Element 2. 

-- Example scenario 2: User only wants to see Elements that are BOTH Red and Hollow. 
select e.* from Elements e where 
(@Properties) --ideally a set containing only Red and Hollow 
in 
(select Text from #masterTable where ElementId = e.Id) 
--Both Red and Hollow are within Element 2's properties (Red, Smooth, Hollow), so Element 2 gets returned, but not Element 1. 


--Example Scenario 3: User only picked the Red option. 
select e.* from Elements e where 
(@Properties) --ideally a set containing only Red 
in 
(select Text from #masterTable where ElementId = e.Id) 
--Red is within both Element 1 and Element 2's properties, so both Element 1 and Element 2 get returned. 

SQL은 "in"비교의 왼쪽에 여러 값을 허용하지 않으므로 위의 구문이 실제로 작동하지 않습니다. 오류를 반환하는 오류 :

Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression. 

여기에도 올바른 트랙에 있습니까? 예제가 오래 걸리거나 혼란 스러울 경우 죄송합니다.

가 여기에 내가 함께 일하고 있어요 정확한 코드입니다 : 요소의 텍스트 필드에 쉼표를 포함하지 않는 것으로 가정

select p.* 
from Products p 
where 
(
    (
     --user can search through gloves, bats, or both 
     p.TypeId = 2 and 'Bat' in (@ProductTypes) 
     and 
     (
      (
       (@BatProperties) COLLATE DATABASE_DEFAULT in 
       (
        select props.Name from PropertyTypes props 
        inner join ProductProperties pp on props.Id = pp.TypeId 
        where pp.ProductId = p.Id 
       ) 
      --still want query to run when no properties are selected 
      ) or not exists(select * from @BatProperties) 
     ) 
    ) 
    or 
    (
     p.TypeId = 1 and 'Glove' in (@ProductTypes) --user can search through gloves, bats, or both 
     and 
     (
      (
       (@GloveProperties) COLLATE DATABASE_DEFAULT in 
       (
        select props.Name from PropertyTypes props 
        inner join ProductProperties pp on props.Id = pp.TypeId 
        where pp.ProductId = p.Id 
       ) 
      --still want query to run when no properties are selected 
      ) or not exists(select * from @GloveProperties) 
     ) 
    ) 
) 
+0

가 실제로 오류가 당신이'= (하위 쿼리)를 사용 말한다 (코드는 생산 표준 아님) 아래와 같이 토큰 화에 사용될 수'서브 쿼리가 하나 개 이상의 행을 반환 할 때. 어떤 행으로 인해 오류가 발생했는지 알 수 있으면 더 쉽게 도움이 될 것입니다 –

+0

@eakron 행 번호가 지정되지 않았습니다. 오류는 훨씬 더 큰 쿼리의 라인 1을 참조합니다.이 로직은 훨씬 더 멀리 파묻혀 있습니다. – AJH

+0

글쎄, 나는 사지에 나가서 잘못된 코드가 우리에게 준 예제에 없다고 말할 것이다. 오류 상태로 = etc 다음에 하위 쿼리가 없습니다. 귀하의 오류는 다른 곳에서 발생합니다. –

답변

0

먼저 매개 변수 문자열을 토큰 화 수있는 이후 수, 임시 테이블에 속성을 채울 원하는 모든 속성을 가진 요소를 얻으려면 #masterTable과 조인하십시오. CTE를가

declare @parameter varchar(1000) 
declare @num_of_params int 
set @num_of_params = 0 
set @parameter = 'Red, Dense, Coarse' 
CREATE TABLE #tmp (id int, string varchar(1000)) 

INSERT INTO #tmp (id, string) 
SELECT 1, @parameter 

;WITH test (id, lft, rght, idx) 
AS 
(
    SELECT t.id 
     ,LEFT(t.string, CHARINDEX(', ', t.string) - 1) 
     ,SUBSTRING(t.string, CHARINDEX(', ', t.string) + 2, DATALENGTH(t.string)) 
     ,0 
    FROM #tmp t 
    UNION ALL 
    SELECT c.id 
     ,CASE WHEN CHARINDEX(', ', c.rght) = 0 THEN c.rght ELSE LEFT(c.rght, CHARINDEX(', ', c.rght) - 1) END 
     ,CASE WHEN CHARINDEX(', ', c.rght) > 0 THEN SUBSTRING(c.rght, CHARINDEX(', ', c.rght) + 2, DATALENGTH(c.rght)) 
      ELSE '' END 
     ,idx + 1 
    FROM test c 
    WHERE DATALENGTH(c.rght) > 0 
) 

select * into #test from test 
select @num_of_params = count(*) from #test 
Drop table #tmp 
select @num_of_params 


select e.* from Elements e where elementID in (
select elementID 
from #masterTable m inner join #test t 
on m.text = t.lft 
group by m.ElementID 
having count(*) = @num_of_params 
) 

drop table #test