执行GROUP BY并获取未在聚合函数中使用的其他列?

时间:2012-05-14 10:46:29

标签: sql sql-server

在下面的代码中,我有两个表。我加入这些,在" Spot"上执行GROUP BY然后通过连接计算出值的MIN()。

问题是我还希望为我的结果行获取Column2的值。目前我不能立即选择它,因为Column2不是GROUP BY的一部分,它不是聚合函数的一部分。

另外,我无法对数据执行第3次JOIN以获取此列,因为我最终会绕圈子,因为我的连接条件将在DerivedValue上,为了得到这个,我需要生成另一个GROUP BY .....我将围成一圈。

如果它有助于理解 - temp4只是一个包含1和0的表,执行一个掩码(因此MIN()是在这两个乘法时完成的......)

编辑:请注意,我加入同一个表的原因是因为我实际上从矩阵中减去了两个值,这是在一行中获取正确值以减去的最简单方法。

SELECT temp3.Column1, min(temp3.DerivedValue * Probability) FROM
    (SELECT temp1.Spot AS Spot, temp1.Vol AS Vol, temp1.Value- temp2.Value AS DerivedValue FROM
        (SELECT Spot, Vol, Value FROM My_Table_1) temp1
    INNER JOIN
        (SELECT Spot, Vol, Value FROM My_Table_1) temp2
    ON temp1.Spot = temp2.Spot) temp3
JOIN
    (SELECT Spot, Vol, Probability FROM My_Table_2) temp4
ON temp3.Spot = temp4.Spot AND temp3.Vol = temp4.Vol
GROUP BY temp3.Spot

3 个答案:

答案 0 :(得分:0)

您无法选择GROUP BY子句或聚合中不存在的列。原因是无法将多行的值压缩到一个数据单元中。例如,如果将20行分组为一行,如何确定要在此行中的结果中选择哪个值?您应该指示查询选择正确的值,或者对其进行分组,或者以某种方式聚合。

否则无法完成。也许考虑改写一下你的问题,为你的确切问题找到一些解决方法。

答案 1 :(得分:0)

从SQL Server 2005中,您可以使用row_number() over()获取与最大值或最小值位于同一行的列数据。

这样的事可能适合你。对temp3.spot进行分区并按计算值排序。这为最小计算值提供了row_number为1。您需要将整个查询放在派生表或CTE中,因为无法在where子句中使用row_number

WITH C AS
(
  SELECT temp3.Spot,
         temp3.DerivedValue * temp4.Probability AS DerivedValue_Probability,
         ROW_NUMBER() OVER(PARTITION BY temp3.spot ORDER BY temp3.DerivedValue * temp4.Probability) as RN
  FROM   (SELECT temp1.Spot                AS Spot,
                 temp1.Vol                 AS Vol,
                 temp1.Value - temp2.Value AS DerivedValue
          FROM   (SELECT Spot,
                         Vol,
                         Value
                  FROM   My_Table_1) temp1
                 INNER JOIN (SELECT Spot,
                                    Vol,
                                    Value
                             FROM   My_Table_1) temp2
                   ON temp1.Spot = temp2.Spot) temp3
         JOIN (SELECT Spot,
                      Vol,
                      Probability
               FROM   My_Table_2) temp4
           ON temp3.Spot = temp4.Spot
              AND temp3.Vol = temp4.Vol
)
SELECT Spot,
       DerivedValue_Probability
FROM C
WHERE RN = 1;

答案 2 :(得分:0)

这看起来像一个复杂的查询来给出一个简单的结果。您的初始连接会生成每个(Spot,Vol)对的副本,并且该对的两个Value值之间存在差异。

(Spot,Vol)对的可能概率仅为0或1,因此您寻找的最小值是这些值差异中最小值的0或1倍。

(Spot,Vol)对的最小值差异必然是该对的最小值(Value) - max(值)。

下面的简单查询应该会为您提供与发布的查询相同的结果。但是,您可能想要完全不同的东西,并且您发布的查询可能是错误的。

select
  V.Spot, V.Vol, min(P.Probability)*(min(V.Value)-max(V.Value)) as minDVtimesProb
from My_Table_1 as V
join My_Table_2 as P
on P.Spot = V.Spot
and P.Vol = V.Vol
group by V.Spot, V.Vol;