2017-09-22 6 views
0

Nouveau ici. J'essaie d'obtenir les utilisateurs actifs quotidiens et hebdomadaires au fil du temps. ils ont 30 jours avant d'être considérés comme inactifs. Mon but est de créer des graphiques qui peuvent être divisés par user_id pour montrer les cohortes, les régions, les catégories, etc.SQL - Inégal gauche rejoindre BigQuery

J'ai créé une table de date pour obtenir tous les jours pour la période et j'ai le tableau des ordres simplifiés avec la base info dont j'ai besoin pour calculer ça.

Je suis en train de faire une jointure gauche pour obtenir le statut par jour à l'aide de la requête SQL suivante:

WITH daily_use AS (
     SELECT 
      __key__.id as user_id 
      , DATE_TRUNC(date(placeOrderDate), day) as activity_date 
     FROM `analysis.Order` 
     where isBuyingGroupOrder = TRUE 
      and testOrder = FALSE 
     GROUP BY 1, 2 
), 
dates as (
     SELECT DATE_ADD(DATE "2016-01-01", INTERVAL d.d DAY) AS date 
     FROM 
      (
      SELECT ROW_NUMBER() OVER(ORDER BY __key__.id) -1 AS d 
      FROM `analysis.Order` 
      ORDER BY __key__.id 
      LIMIT 1096 
     ) AS d 
     order by 1 desc 
    ) 

SELECT 
     daily_use.user_id 
    , wd.date as date 
    , MIN(DATE_DIFF(wd.date, daily_use.activity_date, DAY)) as days_since_last_action 
FROM dates AS wd 

LEFT JOIN daily_use 
    ON wd.date >= daily_use.activity_date 
    AND wd.date < DATE_ADD(daily_use.activity_date, INTERVAL 30 DAY) 

GROUP BY 1,2 

Je reçois cette erreur: LEFT OUTER JOIN ne peut pas être utilisé sans condition est une égalité des champs des deux côtés de la jointure. Dans BigQuery et se demandait comment je peux contourner cela. J'utilise Standard SQL dans BigQuery.

Merci

+0

Copie possible de: https://stackoverflow.com/questions/43858433/bigquery-joining-on-multiple-conditions-using-subqueries-and-or-statements – phroureo

+0

BigQuery essaiera de vous faire utiliser une condition d'égalité depuis cette n'est pas évolutif pour les grandes tables (il n'y a pas de clé commune à utiliser lorsque vous mélangez des données). Que se passe-t-il si vous utilisez CROSS JOIN avec une clause WHERE? –

Répondre

1

est ci-dessous pour BigQuery standard SQL et reproduire la plupart du temps logique dans votre requête à l'exception de ne pas y compris les jours où aucune activité se trouve

#standardSQL 
SELECT 
    daily_use.user_id 
    , wd.date AS DATE 
    , MIN(DATE_DIFF(wd.date, daily_use.activity_date, DAY)) AS days_since_last_action 
FROM dates AS wd 
CROSS JOIN daily_use 
WHERE wd.date BETWEEN 
    daily_use.activity_date AND DATE_ADD(daily_use.activity_date, INTERVAL 30 DAY) 
GROUP BY 1,2 
-- ORDER BY 1,2 

si, pour une raison quelconque vous encore besoin de exactly reproduire votre logique - vous pouvez embrasser ci-dessus avec la dernière jointure gauche comme ci-dessous:

#standardSQL 
SELECT * 
FROM dates AS wd 
LEFT JOIN (
    SELECT 
    daily_use.user_id 
    , wd.date AS date 
    , MIN(DATE_DIFF(wd.date, daily_use.activity_date, DAY)) AS days_since_last_action 
    FROM dates AS wd 
    CROSS JOIN daily_use 
    WHERE wd.date BETWEEN 
    daily_use.activity_date AND DATE_ADD(daily_use.activity_date, INTERVAL 30 DAY) 
    GROUP BY 1,2 
) AS daily_use 
USING (date) 
-- ORDER BY 1,2 
+0

Hey Mikhail Berlyant, Cela répond parfaitement à ma question. Votre première suggestion fonctionne parfaitement. Je n'ai pas besoin de remplir les dates sans données. Les dates dans la gamme et les jours entre les commandes est ce que nous recherchons. Merci beaucoup. – SpasticCamel