計數存在於之前而不存在於之後和之後但不存在於之前的行數
我有一個 Azure SQL 數據庫,一個包含 3 個相關列的表:品牌、ID 和月/年,還有一個臨時表,它簡單地列出了帶有 ID 的月/年。
該表顯示了該給定月份的所有活動 ID 的列表。
Month/Year 是一個日期戳列,日期為月份的第一個。ID 列只是一個 ID。
目標是有一個輸出,每個月將顯示本月活躍但下個月不活躍的所有記錄的計數(流失)和上個月不活躍但活躍的 ID在這個月(新),並按品牌和月份分組,所以:
品牌 | 流失 | 新 | 第 1 個月
| 10 | 12 | 2019-12-01
2 | 11 | 9 | 2019-12-01
我還應該注意到 Table1 有 1900 萬行。
我嘗試了以下程式碼:
Declare @Id int declare @my date set @Id = 300 set @my = '2019-12-01' select t1.[brand], count(c.[ID]) as [churn], count(n.[ID]) as [new], t1.[month/year] from Table1 T1 left join Table1 c on c.[ID] = t1.[ID] and c.[ID] not in (select [ID] from Table1 where [Month/Year] = (select [month/year] from Temp_Date where id = (@Id +1))) left join Table1 n on n.[ID] = T1.[ID] and n.[ID] not in (select [ID] from Table1 where [Month/Year] = (select [month/year] from Temp_Date where id = (@Id -1))) where t1.[Month/Year] = @my group by t1.[Brand], t1.[Month/Year]
儘管它產生了輸出,但我認為它不正確,而且花了很長時間,這可能是由於我在聯接中自由使用了子查詢。
我的問題是 2 倍 - 有人可以幫助以更好的方式計算行數並加入它們嗎?有沒有更好的方法可以在沒有這麼多子查詢的情況下做到這一點?
通常,您應該包含生成表模式並用數據填充它們的腳本。(同樣對於性能問題,您也應該包括執行計劃。)如果沒有真實數據,我無法進行大量測試,但我相信此查詢應該會提高您所看到的性能:
DECLARE @my DATE = '2019-12-01' DECLARE @nextMonthYear DATE = DATEADD(MONTH, 1, @my) DECLARE @prevMonthYear DATE = DATEADD(MONTH, -1, @my) SELECT CurrentMonth.Brand, SUM(CASE WHEN NextMonth.ID IS NULL THEN 1 ELSE 0 END) AS Churn, SUM(CASE WHEN PreviousMonth.ID IS NULL THEN 1 ELSE 0 END) AS New, CurrentMonth.MonthYear FROM Table1 AS CurrentMonth LEFT JOIN Table1 AS NextMonth ON NextMonth.MonthYear = @nextMonthYear AND CurrentMonth.ID = NextMonth.ID LEFT JOIN Table1 AS PreviousMonth ON PreviousMonth.MonthYear = @prevMonthYear AND CurrentMonth.ID = PreviousMonth.ID WHERE CurrentMonth.MonthYear = @my GROUP BY CurrentMonth.Brand, CurrentMonth.MonthYear
這也比一堆子查詢簡單得多(開發人員可以閱讀和 SQL Server 解析)。您可能是對的,不需要的額外加入子查詢是您的性能問題的根源(但我無法在沒有看到執行計劃的情況下驗證這一點)。
上面的查詢所做的是
LEFT JOIN
在其自身上使用 a to Table1 兩次(一次用於 thePreviousMonth
,一次用於 theNextMonth
),ID
以獲取與 . 匹配和不匹配的所有記錄CurrentMonth
。然後使用內部SUM()
帶有CASE
語句的聚合函式,我們可以只總結NULLs
(在andID
中CurrentMonth
不存在的情況)以獲得 and 的計數,並按and分組。PreviousMonth``NextMonth``New``Churn``Brand``MonthYear``CurrentMonth