我正在使用SQL Server 2012.对于一个项目我想要展平一张桌子,但我需要一些帮助。我的桌子。
| ApplicationName | Name | Value | CreatedOn
| Contoso | Description | An example website | 04-04-2014
| Contoso | Description | Nothing | 02-04-2014
| Contoso | Keywords | Contoso, About, Company | 04-04-2014
| Contoso | Keywords | Contoso, Company | 02-04-2014
我想从Name by Application Name获取最后一条修改记录。我想要的结果。
| ApplicationName | Description | Keywords
| Contoso | An example website | Contoso, About, Company
我不喜欢临时表。谁知道怎么做?
非常感谢。
的Jordy
答案 0 :(得分:2)
这是更完整的解决方案:
declare @collist nvarchar(max)
SET @collist = stuff((select distinct ',' + QUOTENAME(name)
FROM table -- your table here
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
declare @q nvarchar(max)
set @q = '
select *
from (
select ApplicationName, name, Value
from (
select *, row_number() over (partition by ApplicationName, name order by CreatedOn desc) as rn
from table -- your table here
where appname = ''contoso''
) as x
where rn = 1
) as source
pivot (
max(Value)
for name in (' + @collist + ')
) as pvt
'
exec (@q)
答案 1 :(得分:0)
您将不得不使用数据透视表来执行此操作。如果Name的值的数量未知,您还需要使用一些动态sql。您可能会发现有用的3篇文章是:
编辑:
这是一个可能的例子
--Get the list of names
DECLARE @values varchar(MAX);
SELECT @values = COALESCE(@values, '') + '[' + Name + '],' FROM table;
SET @values = SUBSTRING(@values, 1, LEN(@values) - 1);
--build the sql string using these names
DECLARE @sql varchar(MAX) = 'SELECT applicationName, ' + @values + 'FROM (';
SET @sql = @sql + 'SELECT applicationName, Name, Value FROM tableName WHERE CreatedOn = (SELECT MAX(CreatedOn) FROM tableName WHERE ApplicationName = @appName) AND applicationName = @appName) AS toPivot';
SET @sql = @sql + 'PIVOT (';
SET @sql = @sql + 'MAX(Value) FOR Name IN (' + @values + ')) As p';
--run sql
DECLARE @ParamDefinition varchar(MAX) = '@appName varchar(MAX)';
DECLARE @selectedApp varchar(MAX) = 'put the app you want here';
EXECUTE sp_executesql @sql, @ParamDefinition, @appName = @selectedApp;
请注意,我假设您对应用程序感兴趣的每个名称的CreatedOn值都相同。
再次编辑:
我的下面的解决方案有一个非常好的技巧,可以计算每个条目的最新日期,如果它们不同的话。
免责声明,因为我在答案窗口中做到了这一点,它可能不是100%正确,但它应该让你非常接近。答案 2 :(得分:0)
这是执行此操作的基本方法。用表替换临时表。
DECLARE @tmp TABLE (
ApplicationName VARCHAR(25),
[Name] VARCHAR(25),
[Value] VARCHAR(100),
CreatedOn Date )
INSERT INTO @tmp VALUES
('Contoso','Description','An example website','04-04-2014'),
('Contoso','Description','Nothing','02-04-2014'),
('Contoso','Keywords','Contoso, About, Company','04-04-2014'),
('Contoso','Keywords','Contoso, Company','02-04-2014')
SELECT a.ApplicationName,
a.[Value] AS [Description],
d.Value AS [Keywords]
FROM @tmp AS a
-- filter the rows by max date
INNER JOIN (SELECT c.applicationName, MAX(c.CreatedOn) AS mCreated
FROM @tmp AS c
GROUP BY c.applicationName
) AS b ON a.ApplicationName = b.ApplicationName AND a.CreatedOn = b.mCreated
AND a.Name = 'Description'
-- go back and get the matching key words
INNER JOIN @tmp AS d ON a.ApplicationName = d.ApplicationName AND d.Name = 'Keywords' AND
d.CreatedOn = a.CreatedOn