我真的想自己想出这个解决方案,但这比我想象的更具挑战性。
我试图检索信息的表格看起来就像下面的表格一样简单。
表: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个的排列。
感谢。
答案 0 :(得分:2)
你的架构很笨拙且非规范化,你应该有3个表,
Car
Feature
CarFeature
CarFeature
表应包含两列,CarId
和FeatureId
。然后你可以做点什么,
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
)