我们有这些表
CREATE TABLE tbl01
(
[id] int NOT NULL PRIMARY KEY,
[name] nvarchar(50) NOT NULL
)
CREATE TABLE tbl02
(
[subId] int NOT NULL PRIMARY KEY ,
[id] int NOT NULL REFERENCES tbl01(id),
[val] nvarchar(50) NULL,
[code] int NULL
)
如果我们运行此查询:
SELECT
tbl01.id, tbl01.name, tbl02.val, tbl02.code
FROM
tbl01
INNER JOIN
tbl02 ON tbl01.id = tbl02.id
我们得到了这些结果:
-------------------------------
id | name | val | code
-------------------------------
1 | one | FirstVal | 1
1 | one | SecondVal | 2
2 | two | YourVal | 1
2 | two | OurVal | 2
3 | three | NotVal | 1
3 | three | ThisVal | 2
-------------------------------
您可以看到每两行都与相同的" id"
相关问题是:我们需要为每个id
检索一条包含所有val
的记录,每个val
将根据列code
<的值返回列中/ p>
if(code = 1) then val as val-1
else if (code = 2) then val as val-2
像这样:
-------------------------------
id | name | val-1 | val-2
-------------------------------
1 | one | FirstVal | SecondVal
2 | two | YourVal | OurVal
3 | three | NotVal | ThisVal
-------------------------------
有什么建议吗?
答案 0 :(得分:2)
使用可以使用MAX和Group By来实现此目的
SELECT id,
name,
MAX([val1]) [val-1],
MAX([val2]) [val-2]
FROM ( SELECT tbl01.id, tbl01.name,
CASE code
WHEN 1 THEN tbl02.val
ELSE ''
END [val1],
CASE code
WHEN 2 THEN tbl02.val
ELSE ''
END [val2]
FROM tbl01
INNER JOIN tbl02 ON tbl01.id = tbl02.id
) Tbl
GROUP BY id, name
答案 1 :(得分:1)
如果总是只有两个值,您可以加入它们甚至更容易,将它们分组:
SELECT tbl01.id as id, Min(tbl01.name) as name, MIN(tbl02.val) as val-1, MAX(tbl02.val) as val-2
FROM tbl01
INNER JOIN tbl02 ON tbl01.id = tbl02.id
GROUP BY tbl02.id
注意:如果不需要,此查询将始终将最低值放在第一列中,最高值放在第二列中:使用连接查询:
如果您总是希望第一列中的代码1和第二列中的代码2:
SELECT tbl01.id as id, tbl01.name as name, tbl02.val as val-1, tbl03.val as val-2
FROM tbl01
INNER JOIN tbl02 ON tbl01.id = tbl02.id
ON tbl02.code = 1
INNER JOIN tbl03 ON tbl01.id = tbl03.id
ON tbl03.code = 2
只有在通过在代码或t-sql存储过程中构建查询时才能获得可变数量的列。
我的建议: 如果它总是值:在查询中加入它们,如果没有,让你的服务器端代码转换数据。 (或者甚至更好,找到一种方法,使其无法转换数据)
答案 2 :(得分:1)
您正在寻找PIVOT运算符(http://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx)吗?
答案 3 :(得分:1)
你已经得到了一些答案,但是有人使用PIVOT作为替代。好处是,如果以后需要额外的列,这种方法很容易扩展
-- SETUP TABLES
DECLARE @t1 TABLE (
[id] int NOT NULL PRIMARY KEY,
[name] nvarchar(50) NOT NULL
)
DECLARE @t2 TABLE(
[subId] int NOT NULL PRIMARY KEY ,
[id] int NOT NULL,
[val] nvarchar(50) NULL,
[code] int NULL
)
-- SAMPLE DATA
INSERT @t1 ( id, name )
VALUES ( 1, 'one'), (2, 'two'), (3, 'three')
INSERT @t2
( subId, id, val, code )
VALUES ( 1,1,'FirstVal', 1), ( 2,1,'SecondVal', 2)
,( 3,2,'YourVal', 1), ( 4,2,'OurVal', 2)
,( 5,3,'NotVal', 1), ( 6,3,'ThisVal', 2)
-- SELECT (using PIVOT)
SELECT id, name, [1] AS 'val-1', [2] AS 'val-2'
FROM
(
SELECT t2.id, t1.name, t2.val, t2.code
FROM @t1 AS t1 JOIN @t2 AS t2 ON t2.id = t1.id
) AS src
PIVOT
(
MIN(val)
FOR code IN ([1], [2])
) AS pvt
结果:
id name val-1 val-2
---------------------------------
1 one FirstVal SecondVal
2 two YourVal OurVal
3 three NotVal ThisVal
答案 4 :(得分:0)
试试这个 - 它使用了一个pivot函数,但它也创建了依赖于代码的动态列
DECLARE @ColumnString varchar(200)
DECLARE @sql varchar(1000)
CREATE TABLE #ColumnValue
(
Value varchar(500)
)
INSERT INTO #ColumnValue (Value)
SELECT DISTINCT '[' + 'value' + Convert(Varchar(20),ROW_NUMBER() Over(Partition by id Order by id )) + ']'
FROM Test
SELECT @ColumnString = COALESCE(@ColumnString + ',', '') + Value
FROM #ColumnValue
Drop table #ColumnValue
SET @sql =
'
SELECT *
FROM
(
SELECT
id,name,val,''value'' + Convert(Varchar(20),ROW_NUMBER() Over(Partition by id Order by id ))as [values]
FROM Test
) AS P
PIVOT
(
MAX(val) FOR [values] IN ('+@ColumnString+')
) AS pv
'
--print @sql
EXEC (@sql)