
我試圖計算一個會員是否在一月份購物,二月份再次購物的比例以及三個月內再次購物的比例。最終創建一個類似于所附影像的表。
我試過下面的代碼。第一個左連接有效,但是當我添加第二個以計算 within_3months 時,會顯示錯誤:“FROM 關鍵字未在預期的位置找到”(對于單獨的行)。我可以離開加入兩次還是必須為列執行單獨的腳本?
, count(distinct B.members)/count(distinct A.members) *100 as 1month_retention_rate
select
year_month_january21
, count(distinct A.members) as num_of_mems_shopped_january21
, count(distinct B.members)as retained_february21
, count(distinct B.members)/count(distinct A.members) *100 as 1month_retention_rate
, count(distinct C.members)/count(distinct A.members) *100 as within_3months
from
(select
members
, year_month as year_month_january21
from table.members t
join table.date tm on t.dt_key = tm.date_key
and year_month = 202101
group by
members
, year_month) A
left join
(select
members
, year_month as year_month_february21
from table.members t
join table.date tm on t.dt_key = tm.date_key
and year_month = 202102
group by
members
, year_month) B on A.members = B.members
left join
(select
members
, year_month as year_month_3months
from table.members t
join table.date tm on t.dt_key = tm.date_key
and year_month between 202102 and 202104
group by
members
, year_month) C on A.members = C.members
group by
year_month_january21;
我已經嘗試離開創建一個單獨的時間表并加入這個。這沒用。單獨進行計算是可行的,但我必須在多個時間范圍內執行此操作,因此需要很長時間。
uj5u.com熱心網友回復:
錯誤不是來自添加的左連接,而是來自as 1month_retention_rate部件,因為它是非法名稱。
您可以通過以下方式更簡單地看到:
select dummy as 1month_retention_rate
from dual;
ORA-00923: 在預期的地方找不到 FROM 關鍵字
您可以更改列別名,使其遵循命名規則(特別是這里,不以數字開頭),或者如果實際需要該特定名稱,那么您可以將其設為帶引號的識別符號 - 通常不是一個好的選擇,但有時可以在查詢的最終輸出中。
小提琴
因此,在您的代碼中,您只需更改新行
, count(distinct B.members)/count(distinct A.members) *100 as 1month_retention_rate
類似于
, count(distinct B.members)/count(distinct A.members) *100 as one_month_retention_rate
或帶引號的識別符號
, count(distinct B.members)/count(distinct A.members) *100 as "1month_retention_rate"
小提琴- 這仍然是錯誤的,但現在使用 ORA-00942,因為我沒有你的表,那是在將你的混淆模式/表名稱更改為合法的名稱之后。
可能有更有效的方法來執行計算,但這是一個單獨的問題......
uj5u.com熱心網友回復:
我可以理解你想要得到:
- 1 月份訪問過的所有成員的計數。
- 1 月訪問并在 2 月再次訪問的所有成員的計數。
- 1 月訪問并在 2 月、火星和 4 月再次訪問的所有成員的計數。
如果我的理解是正確的,那么您可以使用 IF 而不是 LEFT JOIN 來簡化您的內部查詢。看看下面的查詢。假設表成員有一個 ID 欄位:
SELECT
mem_jan AS num_of_mems_shopped_january21,
mem_feb AS retained_february21,
mem_feb / mem_jan * 100 as 1month_retention_rate
mem_3m / mem_jan * 100 as within_3months
FROM(
SELECT
SUM(IF(mm_jan>0,1,0) AS mem_jan,
SUM(IF(mm_jan>0 AND mm_feb>0,1,0) AS mem_feb,
SUM(IF(mm_jan>0 AND mm_count_3m>0,1,0) AS mem_3m
FROM
(
SELECT
t.Id,
SUM(IF(year_month = 202101, 1,0)) AS mm_jan, /*visit for a member in Jan*/
SUM(IF(year_month = 202102, 1,0)) AS mm_feb, /*visit for a member in Feb*/
SUM(IF(year_month between 202102 and 202104,1,0)) AS mem_3m/*visit for a member in 3 months*/
FROM
table.members t
join table.date tm on t.dt_key = tm.date_key
WHERE
year_month between 202101 and 202104
GROUP BY
t.Id
) AS t1
) AS t2
這不是最終運行的查詢,但它可以解釋我的想法。根據您的引擎,您可以使用CASE或IF THEN ELSE
uj5u.com熱心網友回復:
不要使用多個聯接,每月計算每個成員的商店,然后使用條件聚合。
在 Oracle 中,這將是:
SELECT 202101 AS year_month,
COUNT(CASE WHEN cnt_202101 > 0 THEN 1 END)
AS members_shopped_202101,
COUNT(CASE WHEN cnt_202101 > 0 AND cnt_202102 > 0 THEN 1 END)
AS members_retained_202102,
COUNT(CASE WHEN cnt_202101 > 0 AND cnt_202102 > 0 THEN 1 END)
/ COUNT(CASE WHEN cnt_202101 > 0 THEN 1 END) * 100
AS one_month_retention_rate,
COUNT(CASE WHEN cnt_202101 > 0 AND (cnt_202102 > 0 OR cnt_202103 > 0 OR cnt_202104 > 0) THEN 1 END)
/ COUNT(CASE WHEN cnt_202101 > 0 THEN 1 END) * 100
AS within_3months
FROM (
SELECT members,
year_month
FROM members m
INNER JOIN date d
ON m.dt_key = d.date_key
)
PIVOT (
COUNT(*)
FOR year_month IN (
202101 AS cnt_202101,
202102 AS cnt_202102,
202103 AS cnt_202103,
202104 AS cnt_202104
)
);
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/529787.html
標籤:sql甲骨文
下一篇:一張表中的SQL多重選擇陳述句
