有条件的; SQL Server2008的SQL查询/ TSql

时间:2014-01-16 11:26:44

标签: sql sql-server-2008 tsql ssrs-2008

我真的想自己想出这个解决方案,但这比我想象的更具挑战性。

我试图检索信息的表格看起来就像下面的表格一样简单。

表: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)

基本上逻辑应该是这样的,如果每个参数都有一行'是',请列出该行的所有'是'的功能,即使其他功能的参数为'否' 。

另外,我不打算过滤报告。我希望这是存储过程本身。

我当然希望避免多个ifs,考虑到我有4个参数,如果可能不是一个更好的事情那么4个的排列。

感谢。

4 个答案:

答案 0 :(得分:2)

你的架构很笨拙且非规范化,你应该有3个表,

Car

Feature

CarFeature

CarFeature表应包含两列,CarIdFeatureId。然后你可以做点什么,

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

咆哮 {

  

在不更改架构的情况下添加功能不仅容易,   由于支持基于集合的操作,因此提供更好的性能   良好的印象涵盖,总体使用较少的存储,因为你没有   需要存储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'
从本质上讲,非规范化为子查询。两个查询都给出了这样的结果,

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

答案 1 :(得分: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

答案 2 :(得分: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

答案 3 :(得分:0)

- 啊哈!我有点想通了自己(非常高兴):)。由于列的值只能是'y'或'n',所以当参数值为no时忽略, - 我会问它寻找永远不存在的价值。 - 如果有人有更好的方式去做或增强我的(首选)将不胜感激。 - 感谢所有回复的人。由于这是现有表格的一部分,也是一个大型存储过程的一部分,我不愿意回答问题的先前答案。

- 此处变量声明和分配

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 
    )