仅在SQL中转置某些数据

时间:2017-05-15 15:32:47

标签: sql sql-server

我的数据如下:

Company Year         Total   Comment                 
Comp A  01-01-2000   5,000   Checked
Comp A  01-01-2001   6,000   Checked
Comp B  05-05-2007   3,000   Not checked completely
Comp B  05-05-2008   4,000   Checked
Comp C  18-01-2003   1,500   Not checked completely
Comp C  18-01-2002   3,500   Not checked completely

我被要求转置某些数据,但我不相信这可以使用SQL(服务器)完成,所以它看起来像这样:

Company     Base Date   Base Date-1   Comment Base Date      Comment Base Date-1
Comp A      01-01-2001  01-01-2000    Checked                Checked
Comp B      05-05-2008  05-05-2007    Checked                Not completely checked
Comp C      18-01-2003  18-01-2002    Not completely checked Not completely checked

我从未建造过这样的东西。如果我愿意那么Excel可能是更好的选择吗?我应该怎么解决这个问题?

是否可以使用SELECT MAX(基准日期)和MIN(基准日期)?然后,我将如何处理这样的字符串..

3 个答案:

答案 0 :(得分:1)

您可以使用self join执行此操作。但是,您应该考虑像2月29日那样的日期,因为它们只发生在闰年。

select t1.company,t1.year as basedate,t2.year as basedate_1,
t1.comment as comment_basedate,t2.comment as comment_basedate_1
from t t1
left join t t2 on t1.company=t2.company dateadd(year,1,t2.year)=t1.year

如果您只需要公司存在日期值的结果,请将left join更改为inner join。该解决方案假设每天只能有一条评论。

答案 1 :(得分:0)

如果每个只有两行,那就非常简单了。如果有两行以上,你可以这样做 - 基本上连接所有行,然后确保A代表最早的行而B代表最新的行。

SELECT A.Company, A.Year AS [Base Date], B.Year  AS [Base Date 1],
       A.Comment AS [Comment Base Date], B.Comment AS [Comment Base Date 1]
FROM MyTable A
    INNER JOIN MyTable B ON A.Company = B.Company
WHERE A.Year = (SELECT MIN(C.YEAR) FROM MyTable C WHERE C.Company = A.Company)
  AND B.Year = (SELECT MAX(C.YEAR) FROM MyTable C WHERE C.Company = B.Company)

使用Row_Number或其他东西可能有更有效的方法。

答案 2 :(得分:0)

我为每个由desc命令的公司分配的每个记录分配一个行号,通过公共表表达式中的分析函数...然后在行号+ 1和公司上使用左自联接....

这假设您每个公司只需要使用最近2年的1条记录。如果公司只存在1条记录,则第二年可接受空值。如果不是,我们可以将左连接更改为内部并消除两个记录...

我们使用公用表表达式(尽管内联视图也可以工作)为每条记录分配一个行号。然后在我们的自我加入中提供该值,因此我们不必担心不同的日期和最大值。然后,我们使用我们的RowNumber(RN)和公司一起加入2个所需的记录。为了节省一些性能,我们将1个表限制为RN 1,将第二个表限制为RN 2。

WITH CTE AS (
SELECT *, Row_Number() over (Partition by Company Order by Year Desc) RN FROM TABLE)

SELECT A.Company
     , A.Year as Base_Date
     , B.Year as Base_Date1
     , A.comment as Base_Date_Comment
     , B.Comment as Base_Date1_Comment
FROM CTE A
LEFT JOIN CTE  B
  on A.RN+1 = B.RN
 and A.Company = B.Company
 and B.RN = 2
WHERE A.RN = 1 

请注意,RN = 2的限制必须在联接上,因为它是外部联接,或者我们将在没有2年的情况下消除这些公司。 (实质上是让左连接成为内部)

此方法使每行的所有数据列都可用。