1

我觉得这是一个简单的答案,但我似乎无法正确回答..

最初我运行了两个查询,因为我无法弄清楚如何解决这个问题。这是我的初始表“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

我尝试将每个 WINDOW 的 RANGE 更改为 ROWS .. 但它仍然是错误的。

发生的事情是每天的所有分组都没有正确发生,它显示日期是单数的,并且每个值的总和相同,但是会有大约 10-20 行完全相同的 SUMS 和DAYs 数据..

这就是“size”列和“day DESC”的前 5 行的样子:

行天数
1 2017-04-30 1679.27
2 2017-04-29 7292.809999999996
3 2017-04-28 3247.04
4 2017-04-27 2209.2000000000003
5 2017-204-26 293.

但相反,它是这样的:

行天数
1 2017-04-30 1679.27
2 2017-04-30 1679.27
3 2017-04-30 1679.27
4 2017-04-30 1679.27
5 2017-04-30 1679.27

如何防止数据中 SUM 和天数的重复?

4

1 回答 1

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
于 2017-05-09T17:53:42.140 回答