SQL基于匹配值在同一个表中加入

时间:2013-08-01 20:20:05

标签: sql sql-server sql-server-2008

我在SQL Server 2008数据库中有一个包含三列的表:dtindx_nmindx_val

当我跑步时:

SELECT * 
FROM table1 a
WHERE a.indx_nm = 'ABQI' OR a.indx_nm = 'ACNACTR'
ORDER BY indx_nm, dt

我得到的东西(只需选择3000个值中的随机8个)

    # dt--------------indx_nm----------------indx_val
    2009-06-08---------ABQI------------------1001.25
    2009-06-09---------ABQI------------------1002.12
    2010-06-08---------ABQI------------------928.76
    2011-06-10---------ABQI------------------959.97
    2009-06-08--------ACNACTR----------------300.05
    2009-06-09--------ACNACTR----------------341.19
    2010-04-08--------ACNACTR----------------428.26
    2011-07-10--------ACNACTR----------------509.48

有什么方法可以返回看起来像

的结果
    # dt---------indx_nm1-----indx_val1-------indx_nm2------indx_val2
    2009-06-08----ABQI------1001.2------------ACNACTR----------300.05
    2009-06-09----ABQI------1002.12 ----------ACNACTR----------341.19

基本上匹配索引号之间的共享日期,然后将其他indx_nm及其对应的indx_val加入到结果中?

*附录

所以我试图找到ABQIACNACTR之间的协方差。我知道我可以取整个indx_val1的平均值和整个index_val2的平均值,但是有一种方法可以循环遍历整个1000多行的每个值{{{} 1}}和indx_val1输入(xi-x)(yi-y)/ n 我可能更容易在vba上做这个,但我不认为它能够处理它(我有数百个indx_nm,我想确定协方差)

1 个答案:

答案 0 :(得分:2)

要完成此操作,您可以GROUP BY dt,并使用聚合MAX()CASE的组合,返回正确的列,同时将多行与NULL折叠成一行。< / p>

SELECT 
  dt,
  MAX(CASE WHEN indx_nm = 'ABQI' THEN indx_nm ELSE NULL END) AS indx_nm1,
  MAX(CASE WHEN indx_nm = 'ABQI' THEN indx_val ELSE NULL END) AS indx_val1,
  MAX(CASE WHEN indx_nm = 'ACNACTR' THEN indx_nm ELSE NULL END) AS indx_nm2,
  MAX(CASE WHEN indx_nm = 'ACNACTR' THEN indx_val ELSE NULL END) AS indx_val2
FROM table1 a
GROUP BY dt
ORDER BY dt

以下是演示:http://sqlfiddle.com/#!6/2ec65/1

如果没有MAX()聚合,那么dt的每个值最终会有两行,其中ABQIANACTR对是NULLMAX()聚合然后选择null和非null值的“最大”值,从而导致每dt个分组行。

现在,如果您想仅返回 那些dt两个 indx_nm已填充的值(NULL s),你可以将上面的内容包装在子查询中:

SELECT * FROM (
    SELECT 
      dt,
      MAX(CASE WHEN indx_nm = 'ABQI' THEN indx_nm ELSE NULL END) AS indx_nm1,
      MAX(CASE WHEN indx_nm = 'ABQI' THEN indx_val ELSE NULL END) AS indx_val1,
      MAX(CASE WHEN indx_nm = 'ACNACTR' THEN indx_nm ELSE NULL END) AS indx_nm2,
      MAX(CASE WHEN indx_nm = 'ACNACTR' THEN indx_val ELSE NULL END) AS indx_val2
    FROM table1 a
    GROUP BY dt
) indxs
WHERE
  /* Discard those rows where either pair is NULL */
  indx_nm1 IS NOT NULL
  AND indx_nm2 IS NOT NULL
ORDER BY dt

编辑哎呀,错误的WHERE条款不应该在那里。