Ich habe zwei Tabellen in Hive, t1
y t2
>describe t1;
>date_id string
>describe t2;
>messageid string,
createddate string,
userid int
> select * from t1 limit 3;
> 2011-01-01 00:00:00
2011-01-02 00:00:00
2011-01-03 00:00:00
> select * from t2 limit 3;
87211389 2011-01-03 23:57:01 13864753
87211656 2011-01-03 23:57:59 13864769
87211746 2011-01-03 23:58:25 13864785
Was ich möchte, ist die Zählung der drei Tage zurückliegenden eindeutigen userid für ein bestimmtes Datum.
Zum Beispiel, für das Datum 2011-01-03
Ich möchte verschiedene userid von 2011-01-01
zu 2011-01-03
.
für Datum 2011-01-04
Ich möchte verschiedene userid von 2011-01-02
zu 2011-01-04
Ich habe die folgende Abfrage geschrieben. Aber sie gibt kein Drei-Tage-Ergebnis zurück. Stattdessen gibt sie unterschiedliche userid pro Tag zurück.
SELECT to_date(t1.date_id), count(distinct t2.userid) FROM t1 JOIN t2
ON (to_date(t2.createddate) = to_date(t1.date_id))
WHERE date_sub(to_date(t2.createddate),0) > date_sub(to_date(t1.date_id), 3)
AND to_date(t2.createddate) <= to_date(t1.date_id)
GROUP by to_date(t1.date_id);
`to_date()` and `date_sub()` are date function in Hive.
Das heißt, der folgende Teil wird nicht wirksam.
WHERE date_sub(to_date(t2.createddate),0) > date_sub(to_date(t1.date_id), 3)
AND to_date(t2.createddate) <= to_date(t1.date_id)
EDIT: Eine Lösung kann sein (aber es ist super langsam):
SELECT to_date(t3.date_id), count(distinct t3.userid) FROM
(
SELECT * FROM t1 LEFT OUTER JOIN t2
WHERE
(date_sub(to_date(t2.createddate),0) > date_sub(to_date(t1.date_id), 3)
AND to_date(t2.createddate) <= to_date(t1.date_id)
)
) t3
GROUP by to_date(t3.date_id);
UPDATE: Danke für alle Antworten. Sie sind gut.
Aber Hive ist etwas anders als SQL. Leider können sie in HIVE nicht verwendet werden. Meine derzeitige Lösung ist die Verwendung von UNION ALL
.
SELECT * FROM t1 JOIN t2 ON (to_date(t1.date_id) = to_date(t2.createddate))
UNION ALL
SELECT * FROM t1 JOIN t2 ON (to_date(t1.date_id) = date_add(to_date(t2.createddate), 1)
UNION ALL
SELECT * FROM t1 JOIN t2 ON (to_date(t1.date_id) = date_add(to_date(t2.createddate), 2)
Dann mache ich group by
y count
. Auf diese Weise kann ich bekommen, was ich will.
Es ist zwar nicht elegant, aber viel effizienter als cross join
.