2017-05-09 4 views
1

Ce que je ressens est une réponse simple, mais je ne peux pas sembler pour y arriver ..Alternative GROUP BY, lorsqu'une fenêtre ne fonctionne pas correctement .. SQL

Dans un premier temps j'ai couru deux requêtes, parce que je ne pouvais pas comprendre comment résoudre ce problème dans un .. ce fut la requête pour ma table initiale « 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 

qui regroupe toutes mes sommes par jour, ce qui est ce que je suis en train faire. Puis je suis parti la deuxième table JOINTES sur la première en exécutant cette deuxième requête:

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 

qui comme je l'ai dit, a bien fonctionné. Cependant, j'ai besoin de répliquer cela dans son ensemble dans une requête. Je ne peux pas le faire directement, car une clause GROUP BY interfère avec LEFT JOIN. Donc, j'ai essayé de faire toute la première des valeurs de la table, une fonction de fenêtre:

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 

J'ai essayé de changer la gamme de chaque fenêtre pour ROWS .. mais il est encore mal. Qu'est-ce qui se passe, c'est que tout le regroupement par jour ne se passe pas correctement, il montre la date au singulier, et la somme de chaque valeur est la même, mais il y aura environ 10-20 rangées de la exactement les mêmes et données SUMS .. DAYS

C'est ce que la colonne « taille » et 5 premières lignes de « jour DESC » devrait ressembler à:

taille du jour Ligne
1 30/04/2017 1679.27
2 2017-04-29 7292.809999999996
3 2017-04-28 3 247,04
4 2017-04-27 2209,2000000000003
5 2017-04-26 2932,42

mais au contraire, il vient comme ça:

Taille du jour Ligne
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

Comment empêcher la répétition des SUM et des jours dans les données?

+0

Y at-il quelque chose qui vous empêche de mettre la première requête en vue puis référencement dans votre 2ème requête? –

+0

"J'ai besoin de répliquer ceci dans son ensemble dans une requête, je ne peux pas le faire directement, car une clause GROUP BY interfère avec LEFT JOIN." Je n'ai aucune idée de ce à quoi cela fait référence. Vous devriez vraiment simplifier les requêtes afin qu'il soit plus facile à suivre pour les autres. Ensuite, le premier ensemble de requêtes commence par 'scratch.free'. La seconde commence par 'calculs'. Je ne peux vraiment pas suivre ce que vous essayez de faire. –

+0

Désolé pour la confusion, ce sont des extraits d'une plus grande requête, que j'ai essayé de condenser tel quel. Si vous vérifiez les réponses, cela a été résolu d'une manière que je pensais avoir déjà essayée! – nikooters

Répondre

1

Qui, comme je l'ai dit, a bien fonctionné. Cependant, je dois reproduire ce dans son ensemble dans une requête ...

Essayez ci-dessous (pour BigQuery StandardSQL)

C'est tout simple assemblage de vos deux étapes dans un comme vous vouliez!
Si, comme vous le prétendez, ils travaillent pour vous séparément - ci-dessous doit travailler pour vous aussi!

#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

Hey Mikhail, merci pour votre réponse, je ne sais pas pourquoi cela n'a pas fonctionné la première fois quand je l'ai essayé, mais il l'a fait maintenant! – nikooters