如何使用SQL Server压缩表格?

时间:2014-04-04 12:07:33

标签: sql sql-server sql-server-2008 sql-server-2012 ssms

我正在使用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

3 个答案:

答案 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篇文章是:

Pivot Tables

SQL Server Cursors

Dynamic Sql

编辑:

这是一个可能的例子

--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