有没有办法在没有子查询的情况下检索聚合和非聚合值?

时间:2013-06-26 02:31:08

标签: mysql sql

我有一张桌子:

trade_id | stock_code |日期|量

此表包含我所做的所有交易。而且我想知道我上周的金额以及每笔股票的总金额。

stock_code | amount_in_lst_week | amount_remaining

例如:

1 | A | 2013-01-01 | 200 
2 | A | 2013-06-25 |-100 
3 | B | 2013-06-25 | 100 
4 | C | 2013-04-01 | 100 

今天是我们当地时间的2013-06-26,所以我应该得到:

A |-100 | 100
B | 100 | 100
C | 0   | 100 

我认为这不是一件困难的事情,但我写了complex subquery这样的话:

SELECT lst_week.stock_code, 
       lst_week.amount_in_lst_week, 
       total.amount_remaining 
  FROM (SELECT t1.stock_code, 
               SUM(COALESCE(t2.amount, t2.amount, 0)) AS amount_in_lst_week 
          FROM trade t1
     LEFT JOIN trade t2 ON t1.trade_id = t2.trade_id 
                       AND TO_DAYS(NOW()) - TO_DAYS(t1.date) <= 7
      GROUP BY t1.stock_code) lst_week,
       (SELECT stock_code, SUM(amount) AS amount_remaining 
          FROM trade
      GROUP BY stock_code) total 
 WHERE lst_week.stock_code = total.stock_code;

它有效,但我想知道是否可以这样做没有子查询?或者任何更简单的方式?谢谢。

3 个答案:

答案 0 :(得分:1)

大多数数据库都支持窗口功能。你可以得到你想要的东西:

select stock_code,
       sum(case when date >= CURRENT_TIMESTAMP - 7 then amount_remaining else 0
           end) as amount_in_lst_week, 
       sum(sum(amount_remaining)) over ()
from trade
group by stock_code, amount_in_lst_week ;

确切的日期/时间函数取决于数据库。例如,在SQL Server中,您将使用:

when date >= cast(CURRENT_TIMESTAMP - 7 as date)

在Oracle中:

when date >= trunc(sysdate - 7)

MySQL不支持窗口函数,因此您必须使用连接或相关子查询来执行此操作:

select stock_code,
       sum(camount_remaining) as amount_in_lst_week, 
       (select sum(amount_remaining) from trade t)
from trade t
where date >= now() - interval 7 days 
group by stock_code, amount_in_lst_week ;

答案 1 :(得分:1)

这个怎么样:

select 
     Stock_code
    ,[1st week] = sum(case when [date] >= getDate()-7 then amount else 0 end)
    ,remainder = sum(amount)
from data
group by Stock_code

答案 2 :(得分:0)

你可以试试这个:

SELECT t.stock_code, 
       Coalesce(t2.amount, 0) AS `amount_in_lst_week`, 
       Sum(t.amount)          AS `amount_remaining` 
FROM   trade t 
       LEFT JOIN (SELECT stock_code, 
                         sum(amount) as `amount` 
                  FROM   trade 
                  WHERE  date BETWEEN Date_add(CURRENT_DATE(), INTERVAL -7 day) 
                                      AND 
                                      CURRENT_DATE() GROUP BY stock_code) t2 
              ON t2.stock_code = t.stock_code 
GROUP  BY t.stock_code; 

虽然它仍然存在子查询......

SQLFiddle sample