2014-01-16 3 views
1

저는이 솔루션에 대해 나 자신이 직접 솔루션을 제안하려고했지만 이것이 생각했던 것보다 약간 더 어려워졌습니다.조건부 여기서; SQLServer2008 용 Sql 쿼리/TSql

정보를 검색하려고하는 표는 다음과 같은 간단한 형태로 표시됩니다.

테이블 : CarFeatures SSRS를 보고서에

+---+---+---+---+-----+ 
|Car|Nav|Bth|Eco|Radio| 
+---+---+---+---+-----+ 
|a |y |n |n |y | 
+---+---+---+---+-----+ 
|b |n |y |n |n | 
+---+---+---+---+-----+ 
|c |n |n |y |n | 
+---+---+---+---+-----+ 
|d |n |y |y |n | 
+---+---+---+---+-----+ 
|e |y |n |n |n | 
+---+---+---+---+-----+ 

, 나는 주어진 매개 변수의 모든 기능을 가지고 있습니다 모든 자동차를 표시해야합니다. 그러면 Nav-yes/no, Bth-yes/no, Eco-yes/no, Radio-yes/no와 같은 보고서의 매개 변수가 수신됩니다.

예를 들어 매개 변수 입력이 네비게이션의 경우 '예'이고 다른 사람의 경우 '아니오'인 경우 결과 테이블은 다음과 같아야합니다.

+---+----------+ 
|Car|Features | 
+---+----------+ 
|a |Nav, Radio| 
+---+----------+ 
|e |Nav  | 
+---+----------+ 

나는 이것이 간단 할 것이라고 생각했지만, 쿼리를 완료하려고 시도 할 때, 이것은 나를 미치게 만든다. 아래는 내가 처음에 필요로하는 것을 얻을 것이라고 생각했던 것이지만 그렇지 않다. 있는 모든 매개 변수에 대한 행이있는 경우

select Car, 
case when @nav = 'y' then 'Nav ' else '' end + 
case when @bth = 'y' then 'Bth ' else '' end + 
case when @eco = 'y' then 'Eco ' else '' end + 
case when @radio = 'y' then 'Radio ' else '' end As Features 
from CarFeatures 
where (nav = @nav -- here I don't want the row to be picked if the input is 'n' 
or bth = @bth 
or eco = @eco 
or radio = @radio) 

은 기본적으로 논리는, 같은 것을해야한다 '예'매개 변수가 '아니오'에도 불구하고, '예'그 행으로 나에게 모든 기능을 나열 그 다른 기능들.

또한 보고서를 필터링 할 생각도 없습니다. 나는 이것을 저장 proc 자체에 있기를 원한다.

필자는 4 개의 매개 변수와 4 개의 순열을 고려할 때 ifs를 여러 번 피하는 것이 좋을 것입니다.

감사합니다.

+0

, 당신이 원하는대로 쿼리 문자열을 구축하고 EXEC-경우 else' 절차는 @SQL의 NVARCHAR (max)를 선언 할 수 – Milen

+0

저장 논리 당신은 '사용할 수 있습니다 (@SQL)를 임시 테이블에 저장하거나 호출자에게 다시 보냅니다. FOR XML 사용법을 볼 수도 있습니다. 이 방법을 사용하면 자동차 기능을 하나의 열에 연결하고 다른 자동차는 자동차에 연결할 수 있습니다. – Pierre

+0

이것은 비정규 화 된 데이터 문제에 대한 것입니다. – Jodrell

답변

0

--Aha! 나는 일종의 자신을 알아 냈습니다 (매우 행복합니다 :). 열의 값은 'y'또는 'n'일 수 있으므로 매개 변수 값이 no 일 때 무시해야합니다. - 나는 절대 존재하지 않을 값을 찾도록 요청할 것입니다. - 누구든지 더 나은 방법을 사용하거나 내가 선호하는 것을 향상시키는 것이 좋습니다. - 답변 한 모든 사람에게 감사드립니다. 이것은 이미 존재하는 테이블의 일부이고 또한 큰 저장 proc의 조각이기 때문에 나는 그 질문에 대한 이전의 대답으로 가기를 꺼려했다. 여기

--variable 선언하고 할당

select Car, 
case when @nav = 'y' then 'Nav ' else '' end + 
case when @bth = 'y' then 'Bth ' else '' end + 
case when @eco = 'y' then 'Eco ' else '' end + 
case when @radio = 'y' then 'Radio ' else '' end As Features 
from CarFeatures 
where (nav = (case when @nav = 'y' then 'Y' else 'B' end 
       OR case when @bth = 'y' then 'Y' else 'B' end 
       OR case when @eco = 'y' then 'Y' else 'B' end 
       OR case when @radio = 'y' then 'Y' else 'B' end 
    ) 
2

스키마 당신은 CarFeature 표는 두 개의 열, CarIdFeatureId 구성되어야 3 표,

Car 

Feature 

CarFeature 

가 있어야 어색하고 denormalised입니다. 그런 다음이 가 {

이 가

뿐만 아니라 이 덮여 그것 때문에 세트 기반 작업의 지원의 스키마를 변경하지 않고 제공하는 더 나은 성능을 기능을 쉽게 추가 할 것 같은,

SELECT DISTINCT 
      cr.CarId 
    FROM 
      CarFeature cr 
    WHERE 
      cr.FeatureId IN SelectedFeatures; 

호언 장담을 할 수 좋은 indesses에 의해, 당신은 아무 더 이상 저장할 필요가 없기 때문에 더 적은 저장 장치를 전체적으로 사용하십시오. 의 40 년 이상으로 뒷받침 된 좋은 패턴과 을 잘 준수 할 것입니다. 노력과 명료화.

} 어떤 이유로, 당신은 데이터 또는 스키마를 변경할 수있는 경우


,이 같은 열을 UNPIVOTFiddle Here

SELECT 
     p.Car, 
     p.Feature 
    FROM 
     (
     SELECT 
      Car, 
      Nav, 
      Bth, 
      Eco, 
      Radio 
     FROM 
      CarFeatures) cf 
    UNPIVOT (Value For Feature In (Nav, Bth, Eco, Radio)) p 
    WHERE 
     p.Value='Y'; 

또는, 당신은 그것을 할 수 이런 옛 스타일 Fiddle Here,

SELECT 
     Car, 
     'Nav' Feature 
    FROM 
     CarFeatures 
    WHERE 
     Nav = 'Y' 
UNION ALL 
SELECT 
     Car, 
     'Bth' Feature 
    FROM 
     CarFeatures 
    WHERE 
    Bth = 'Y' 
UNION ALL 
SELECT 
     Car, 
     'Eco' Feature 
    FROM 
     CarFeatures 
    WHERE 
     Eco = 'Y' 
UNION ALL 
SELECT 
     Car, 
     'Radio' Feature 
    FROM 
     CarFeatures 
    WHERE 
    Radio = 'Y' 

을 본질적으로 부질의로 비정규 화합니다. 두 쿼리 ...........

CAR FEATURE 
A  Nav 
A  Radio 
B  Bth 
B  Radio 
C  Eco 
D  Bth 
D  Eco 
E  Nav 
+0

@jordell - 당신이 옳을 수도 있고, 당신의 말/설명에 동의합니다. 그러나이 테이블은 기존 테이블이며이 시점에서 정규화는 최소한 하나의 상황에서 벗어날 수 있습니다. 내 의견으로는 너무 많은 시나리오를 고려해야하는 경우 다른면을 고려해야 할 수도 있습니다. – NoSaidTheCompiler

0

이 그 작업을 시도,이 같은 결과를

declare @table table (Car char(1),Nav char(1),Bth char(1),Eco char(1),Radio char(1)) 
insert into @table 
select 'a', 'y' , 'n' , 'n', 'y' 
union all 
select 'b', 'n' , 'y' , 'n', 'n' 
union all 
select 'c', 'n' , 'n' , 'y', 'n' 
union all 
select 'd', 'n' , 'y' , 'y', 'n' 
union all 
select 'e', 'y' , 'n' , 'n', 'n' 

select * from @table 


select a.car, 
Nav = left((case when a.nav = 'y' then 'Nav, ' else '' end) + 
(case when a.bth = 'y' then 'Bth, ' else '' end)+ 
(case when a.Eco = 'y' then 'Eco, ' else '' end)+ 
(case when a.Radio = 'y' then 'Radio,' else '' end), 
(len(((case when a.nav = 'y' then 'Nav, ' else '' end) + 
(case when a.bth = 'y' then 'Bth, ' else '' end)+ 
(case when a.Eco = 'y' then 'Eco, ' else '' end)+ 
(case when a.Radio = 'y' then 'Radio,' else '' end)))-1)) 
from @table a 
1
Try This, I believe this will solve your purpose.. 

SELECT Car, 
    tblPivot.Property AS Features, 
    tblPivot.Value 
    INTO #tmpFeature 
FROM  
(SELECT CONVERT(sql_variant,Car) AS Car,CONVERT(sql_variant,NAV) AS NAV,   CONVERT(sql_variant,BTH) AS BTH,  CONVERT(sql_variant,ECO) AS ECO, 
CONVERT(sql_variant,Radio) AS Radio FROM CarFeatures) CarFeatures 
UNPIVOT (Value For Property In (NAV,BTH, ECO, Radio)) as tblPivot 
Where tblPivot.Value='y' 


SELECT 
    Car, 
    STUFF((
    SELECT ', ' + Features 
    FROM #tmpFeature 
    WHERE (Car = Results.Car) 
    FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)') 
    ,1,2,'') AS Features 
FROM #tmpFeature Results 
GROUP BY Car