2013-06-26 77 views
2

我有一個下表:有沒有辦法檢索沒有子查詢的聚集值和非聚合值?

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年6月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; 

它的作品,但我想知道是否可以做到這一點沒有子查詢?或者任何更簡單的方式?謝謝。

+2

您正在使用什麼數據庫管理系統? –

+0

看起來像MySQL ... – sgeddes

+1

我不認爲子查詢是壞的。我做了一個小實驗,雖然它不完全科學,但我認爲它有助於說明http://www.chrislondon.co/joins-vs-subqueries/ – chrislondon

回答

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 
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 ; 
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