日期:2014-05-17 浏览次数:20766 次
有一张表Test_A 货名 备注 钟表 2011年进货 粮食 2012年进货 还有一张表Test_B 货名 别名 粮食 大米 粮食 米饭 现在希望通过一个视图得到这样一张表,数据如下: 货名 别名一 别名二 备注 钟表 2011年进货 粮食 大米 米饭 2012年进货 请问该怎么样写这个视图?
--> 测试数据:[tTest_A]
IF OBJECT_ID('[tTest_A]') IS NOT NULL DROP TABLE [tTest_A]
GO
CREATE TABLE [tTest_A]([货名] VARCHAR(4),[备注] VARCHAR(10))
INSERT [tTest_A]
SELECT '钟表','2011年进货' UNION ALL
SELECT '粮食','2012年进货'
--> 测试数据:[Test_B]
IF OBJECT_ID('[Test_B]') IS NOT NULL DROP TABLE [Test_B]
GO
CREATE TABLE [Test_B]([货名] VARCHAR(4),[别名] VARCHAR(4))
INSERT [Test_B]
SELECT '粮食','大米' UNION ALL
SELECT '粮食','米饭'
--------------开始查询--------------------------
--SELECT a.[货名],CASE b.别名 WHEN b.[货名]=a.[货名] then FROM [tTest_A]
----------------结果----------------------------
/*
*/
DECLARE @s VARCHAR(MAX)
SELECT @s = ISNULL(@s + ',', '') + QUOTENAME(row_id)
FROM (
SELECT row_number() OVER ( PARTITION BY a.货名 ORDER BY b.别名 ) AS row_id
FROM [tTest_A] AS a
INNER JOIN [Test_B] AS b
ON a.[货名] = b.[货名]
) t
SELECT @s ='
SELECT *
FROM (
SELECT a.货名 ,
a.备注 ,
b.别名 ,
row_number() OVER ( PARTITION BY a.货名 ORDER BY b.别名 ) AS row_id
FROM [tTest_A] AS a
LEFT JOIN [Test_B] AS b
ON a.[货名] = b.[货名]
) a
PIVOT (MAX(别名) FOR row_id IN('+@s+'))b
'
EXEC(@s)
----------------结果----------------------------
/*
货名 备注 1 2
---- ---------- ---- ----
钟表 2011年进货 NULL NULL
粮食 2012年进货 大米 米饭
(2 行受影响)
*/
------解决方案--------------------
use db;
IF OBJECT_ID('[tTest_A]') IS NOT NULL DROP TABLE [tTest_A]
GO
CREATE TABLE [tTest_A]([货名] VARCHAR(4),[备注] VARCHAR(10))
INSERT [tTest_A]
SELECT '钟表','2011年进货' UNION ALL
SELECT '粮食','2012年进货'
--> 测试数据:[Test_B]
IF OBJECT_ID('[Test_B]') IS NOT NULL DROP TABLE [Test_B]
GO
CREATE TABLE [Test_B]([货名] VARCHAR(4),[别名] VARCHAR(4))
INSERT [Test_B]
SELECT '粮食','大米' UNION ALL
SELECT '粮食','米饭' union all
select '粮食','小米';
declare @sql nvarchar(max)=''
declare @s1 nvarchar(max)='';
declare @s2 nvarchar(max)='';
;with cte as (
select a.货名,a.备注,b.别名,rn=ROW_NUMBER() over(partition by a.货名,a.备注 order by getdate()) from tTest_A a left join test_b b on a.货名=b.货名
),c1 as (
select w.rn from cte w join cte v on w.货名=v.货名 and w.备注=v.备注
where v.rn =(select top 1 rn from cte order by rn desc)
)
select @s1='select 货名,备注'+(select ',['+CAST(rn as varchar(10))+'] as [别名'+CAST(rn as varchar(10))+']'
from c1 for xml path('')), @s2='max(别名) for rn in ('+STUFF((select ',['+CAST(rn as varchar(10))+']' from c1 for xml path('')),1,1,'')+')';
set @sql=@s1+' from (select a.货名,a.备注,b.别名,rn=ROW_NUMBER() over(partition by a.货名,a.备注 order by getdate()) from tTest_A a left join test_b b on a.货名=b.货名) w pivot ('+@s2+') p'
exec(@sql)
/*
货名 备注 别名1 别名2 别名3
---- ---------- ---- ---- ----
钟表 2011年进货 NULL NULL NULL
粮食 2012年进货 大米 米饭 小米
*/
/*--对应的静态
select 货名,备注,[1] as [别名一],[2] as [别名二] from (
select a.货名,a.备注,b.别名,rn=ROW_NUMBER() over(partition by a.货名,a.备注 order by getdate()) from tTest_A a left join test_b b on a.货名=b.货名
) w pivot (max(别名) for rn in ([1],[2])) p
*/
------解决方案--------------------
if object_id('Test_A') is not null
drop table Test_A
go
create table Test_A (货名 varchar(8),备注 varchar(40))
insert Test_A
select '钟表','2011年进货' union all
select