2017-05-09 35 views
1

這我覺得是一個簡單的答案,但我似乎無法得到它的權利..替代GROUP BY,當窗口無法正常工作.. SQL

起初我跑了兩個查詢,因爲我無法弄清楚如何在一個解決這個問題。這是我的初始表查詢「free2」:

WITH prep AS (
     SELECT *, 
      (((odds - 1)/div) + 1) AS ew_odds, 
      (odds*size) AS possible_win_returns, 
      (((odds - 1)/div) + 1)*size AS possible_ew_returns 
     FROM scratch.free 
    ), 

    prof AS(
     SELECT *, 
      (possible_ew_returns+possible_win_returns) AS possible_total_win, 
      (possible_win_returns*win) - size AS win_profit, 
      (possible_ew_returns*places) - size AS ew_profit 
     FROM prep 
    ) 

    SELECT 
     date_trunc(prof.date, DAY) AS DAY, 
     SUM(ew_odds) AS ew_odds, 
     SUM(size) AS size, 
     SUM(odds) AS odds, 
     SUM(places) AS places, 
     SUM(div) AS divisor, 
     SUM (total_size) AS total_size, 
     SUM(won) AS profit, 
     SUM(ew_profit) AS ew_prof, 
     SUM(win_profit) AS win_prof, 
     SUM(possible_total_win) AS pos_tot_win, 
     SUM(possible_ew_returns) AS pos_ew_ret, 
     SUM(possible_win_returns) AS pos_win_ret 
    FROM prof 
    GROUP BY 1 
    ORDER BY day DESC 

其分組我一天的所有款項,這是我想去做。然後,我通過運行第二個查詢,將第二個表加到第一個表上:

SELECT d.*, 
    f.ew_odds, 
    f.size, 
    f.odds, 
    f.places, 
    f.divisor, 
    f.total_size, 
    f.profit, 
    f.ew_prof AS ew_profit, 
    f.win_prof AS win_profit, 
    f.pos_tot_win AS possible_total_win, 
    f.pos_ew_ret AS possible_ew_returns, 
    f.pos_win_ret AS possible_win_returns, 
    date_trunc(d.day, week) AS week, 
    date_trunc(d.day, month) AS month, 
    date_trunc(d.day, year) AS year, 
    date_trunc(d.day, quarter) AS quarter 
FROM scratch.free2 AS f 
LEFT JOIN accounts.daily_movement AS d 
    ON d.day = f.day 

正如我所說的,工作正常。但是,我需要在一個查詢中將其作爲一個整體進行復制。我不能直接這樣做,因爲GROUP BY子句干擾了LEFT JOIN。所以我試圖讓所有的第一個表的值,窗口函數:

prof AS (
    SELECT *, 
     (possible_ew_returns+possible_win_returns) AS possible_total_win, 
     (possible_win_returns*win) - size AS win_profit, 
     (possible_ew_returns*places) - size AS ew_profit, 
     date_trunc(date, DAY) AS day 
    FROM calculations 
) 

sum AS (
    SELECT prof.day, 
    SUM(prof.ew_odds) 
     OVER (PARTITION BY prof.day RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) 
     AS ew_odds, 
    SUM(prof.size) 
     OVER (PARTITION BY prof.day RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) 
     AS size, 
    SUM(prof.odds) 
     OVER (PARTITION BY prof.day RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) 
     AS odds, 
    SUM(prof.places) 
     OVER (PARTITION BY prof.day RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) 
     AS places, 
    SUM(prof.div) 
     OVER (PARTITION BY prof.day RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) 
     AS divisor, 
    SUM(prof.total_size) 
     OVER (PARTITION BY prof.day RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) 
     AS total_size, 
    SUM(prof.won) 
     OVER (PARTITION BY prof.day RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) 
     AS won, 
    SUM(prof.rico) 
     OVER (PARTITION BY prof.day RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) 
     AS rico, 
    SUM(prof.won) 
     OVER (PARTITION BY prof.day RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) 
     AS profit, 
    SUM(prof.ew_profit) 
     OVER (PARTITION BY prof.day RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) 
     AS ew_prof, 
    SUM(prof.win_profit) 
     OVER (PARTITION BY prof.day RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) 
     AS win_prof, 
    SUM(prof.possible_total_win) 
     OVER (PARTITION BY prof.day RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) 
     AS possible_tot_win, 
    SUM(prof.possible_ew_returns) 
     OVER (PARTITION BY prof.day RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) 
     AS possible_ew_returns, 
    SUM(prof.possible_win_returns) 
     OVER (PARTITION BY prof.day RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) 
     AS possible_win_returns 
    FROM prof) 

SELECT 
    sum.* 
    d.total_euros, 
    d.profit_bf_exp, 
    d.percentage_profit, 
    d.profit_aft_exp, 
    d.brendan_profit, 
    d.brendan_transactions, 
    d.brendan_daily, 
    d.brendan_percentage, 
    d.michael_profit, 
    d.michael_transactions, 
    d.michael_daily, 
    d.michael_percentage, 
    d.general_expenses, 
    d.thiago_payment, 
    d.pedro_payment, 
    d.rodrigues_payment, 
    d.felipe_payment, 
    d.expenses_notes, 
    d.details 
FROM sum 
LEFT JOIN accounts.daily_movement AS d ON d.day = sum.day 
ORDER BY sum.day DESC 

我試圖改變每個窗口範圍的行..但它仍然是錯誤的。

發生的事情是,每天的所有分組都沒有正確發生,它顯示的日期是單數,並且每個值的總和相同,但會有大約10-20行的完全相同的總和及天的數據..

這是「大小」欄和前5行「日DESC」的應該是什麼樣子:

行天大小
1 2017年4月30日1679.27
2 2017-04-29 7292.809999999996
3 2017-04-28 3 247.04
4 2017年4月27日2209.2000000000003
5 2017年4月26日2932.42

而是它出來是這樣的:

行天大小
1 2017-04- 30 1679.27
2 2017年4月30日1679.27
3 2017年4月30日1679.27
4 2017年4月30日1679.27
5 2017年4月30日1679。 27

如何防止數據中SUM和天數的重複?

+0

有什麼阻止你把第一個查詢到視圖然後在第二個查詢參照呢? –

+0

「我需要在一個查詢中將其作爲一個整體進行復制,因爲GROUP BY子句干擾了LEFT JOIN,所以我不能直接這樣做。」我不知道那是指什麼。您應該真正簡化查詢,以便其他人更容易遵循。然後,第一組查詢以'scratch.free'開頭。第二個以「計算」開始。我真的不能跟隨你所嘗試的。 –

+0

對不起,我試圖壓縮一個更大的查詢片段,因爲這是一個片段。如果你檢查答案,它已經以我認爲我已經嘗試過的方式解決了! – nikooters

回答

1

正如我所說,工作得很好。不過,我需要在一個查詢中複製此作爲一個整體......

下面嘗試(可供BigQuery StandardSQL)

這是在一個你的兩個步驟只是簡單的組裝,你想要的!
如果你聲稱,他們單獨爲你工作 - 下面也必須爲你工作!

#standardSQL 
WITH prep AS (
    SELECT *, 
    (((odds - 1)/DIV) + 1) AS ew_odds, 
    (odds*size) AS possible_win_returns, 
    (((odds - 1)/DIV) + 1)*size AS possible_ew_returns 
    FROM scratch.free 
), 
prof AS(
    SELECT *, 
    (possible_ew_returns+possible_win_returns) AS possible_total_win, 
    (possible_win_returns*win) - size AS win_profit, 
    (possible_ew_returns*places) - size AS ew_profit 
    FROM prep 
), 
free2 AS (
    SELECT 
    DATE_TRUNC(prof.date, DAY) AS DAY, 
    SUM(ew_odds) AS ew_odds, 
    SUM(size) AS size, 
    SUM(odds) AS odds, 
    SUM(places) AS places, 
    SUM(DIV) AS divisor, 
    SUM (total_size) AS total_size, 
    SUM(won) AS profit, 
    SUM(ew_profit) AS ew_prof, 
    SUM(win_profit) AS win_prof, 
    SUM(possible_total_win) AS pos_tot_win, 
    SUM(possible_ew_returns) AS pos_ew_ret, 
    SUM(possible_win_returns) AS pos_win_ret 
    FROM prof 
    GROUP BY 1 
) 
SELECT d.*, 
    f.ew_odds, 
    f.size, 
    f.odds, 
    f.places, 
    f.divisor, 
    f.total_size, 
    f.profit, 
    f.ew_prof AS ew_profit, 
    f.win_prof AS win_profit, 
    f.pos_tot_win AS possible_total_win, 
    f.pos_ew_ret AS possible_ew_returns, 
    f.pos_win_ret AS possible_win_returns, 
    DATE_TRUNC(d.day, week) AS week, 
    DATE_TRUNC(d.day, month) AS month, 
    DATE_TRUNC(d.day, year) AS year, 
    DATE_TRUNC(d.day, quarter) AS quarter 
FROM free2 AS f 
LEFT JOIN accounts.daily_movement AS d 
ON d.day = f.day 
+0

嘿米哈伊爾,謝謝你的回答,我不知道爲什麼第一次嘗試時它不起作用,但它現在做到了! – nikooters