2014-01-16 32 views
1

我真的想自己想出這個解決方案,但事實證明這比我想象的要稍微複雜一些。有條件的地方;對於SQLServer2008 SQL查詢/ TSQL

我試圖檢索信息的表格看起來像下面的簡單形式。

表:CarFeatures

+---+---+---+---+-----+ 
|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 | 
+---+---+---+---+-----+ 

在SSRS報告,我需要顯示所有具有所有從給定參數的功能的汽車。這將從報告中接收參數,如: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) 

基本邏輯應該是這樣的,如果沒有爲每個參數是一排「是」,列出了我所有特性,「是」該行,即使參數是「不」爲那些其他功能。

此外,我不考慮過濾報告。我希望這是存儲過程本身。

我當然希望避免考慮我有4個參數和4中,如果可能不是一個更好的事情做多排列IFS。

謝謝。

+0

你可以使用'如果-else'邏輯存儲過程 – Milen

+0

你可以聲明@SQL爲nvarchar(最大),建立一個查詢字符串,你想和EXEC( @SQL)放到臨時表中,或者回到調用者。您還可以查看FOR XML的用法。通過這種方式,您可以將汽車功能連接成一列,而另一輛車連接到另一輛車。 – Pierre

+0

這是針對非規格化數據的問題之一。 – Jodrell

回答

0

--Aha!我有點想通了(非常高興):)。由於列的值只能是'y'或'n',因此在參數值爲no時忽略,我只會要求它查找永遠不會存在的值。 - 如果任何人有更好的方式來做或增強我的(首選)將不勝感激。 - 感謝所有回覆的人。既然這是已經存在的表的一部分,也是一個大的存儲過程,我不願意回答以前的問題。這裏

--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

你的架構是笨拙和去歸一化,就應該有3個表,

Car 

Feature 

CarFeature 

CarFeature表應包括兩列,CarIdFeatureId的。然後你可以不喜歡,

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

咆哮 {

它不僅會很容易地添加功能,而無需更改架構, 提供更好的性能,因爲支持基於組操作 覆蓋良好的indecies,整體使用更少的存儲,因爲你沒有 不再需要存儲No值,你要遵守一些知名 深思熟慮,並建立模式通過40多年的 支持發展努力和澄清。

}


如果出於某種原因,你不能改變的數據或模式,可以UNPIVOT這樣的列,Fiddle 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' 

本質上,denormalise到子查詢。這兩個查詢得出的結果是這樣,

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