MySQL:在IF子句中放置WHERE语句的优雅方式

时间:2017-07-19 07:02:56

标签: mysql

我有一个包含一些数据的mysql表:

Ticker    Size    Price
A         0       20
A         1       21
B         1       20
B         -1      21
B         -1      22

如果整体大小不为零,我想写一个SQL查询来返回每个股票代码的(交易量加权)平均价格。如果总体尺寸为正,则平均价格仅为正尺寸的平均值(反之亦然)。

例如,在这种情况下,查询应返回:

Ticker    NetSize    VWAP
A         1          21 (average: 21)
B         -1         21.5 (average: 21,22)

我试图提出一个看起来像这样的查询:

SELECT Ticker, Sum(Size) AS NetSize, 
    IF(SUM(SIZE)>0, (SELECT SUM(Size*Price)/SUM(Size) FROM mysqltable WHERE Size>0 (and many conditions...)),
    IF(SUM(SIZE)<0, (SELECT SUM(Size*Price)/SUM(Size) FROM mysqltable WHERE Size<0 (and many conditions...)),
    0)) AS VWAP
FROM mysqltable
WHERE <many conditions>

但是,这样做需要重复长WHERE子句以及表的名称。是否有更优雅的方式来实现同样的目标?

非常感谢您提供的任何帮助!

2 个答案:

答案 0 :(得分:2)

SELECT Ticker, Sum(Size) AS NetSize, 
   CASE WHEN SUM(SIZE)>0 THEN SUM(Size*Price)/SUM(Size) 
        WHEN SUM(SIZE)<0 THEN SUM(Size*Price)/SUM(Size)
        ELSE 0 
   END AS VWAP
FROM mysqltable
WHERE <many conditions>

尝试以上查询。

您正尝试对方案SUM(SIZE)>0 or SUM(SIZE) < 0进行相同的计算。

我认为这没有道理。

我仍然按照原样处理你的情况,并尝试解决你的问题。

答案 1 :(得分:2)

我认为您可以将查询简化为:

SELECT Ticker, SUM(Size) AS NetSize,
       CASE 
          WHEN SUM(Size) > 0 THEN AVG(CASE WHEN Size > 0 THEN Price END)
          WHEN SUM(Size) < 0 THEN AVG(CASE WHEN Size < 0 THEN Price END)
          ELSE 0
       END AS VWAP       
FROM mytable
GROUP BY Ticker;

Demo here