Mysql
查詢獲取列中所有唯一條目的總和
目前我正在使用 mysql 返回具有相同單詞的列中所有數據的總和。為此,我使用以下查詢:
SELECT SUM(CASE WHEN status_to = 'Draft' THEN 1 END) AS draft, SUM(CASE WHEN status_to = 'Unpublish' THEN 1 END) AS unpublish, SUM(CASE WHEN status_to = 'Publish' THEN 1 END) AS publish, SUM(CASE WHEN status_to = 'Action' THEN 1 END) AS action, SUM(CASE WHEN status_to = 'Unlisted' THEN 1 END) AS unlisted, SUM(CASE WHEN status_to = 'Sold' THEN 1 END) AS sold, SUM(CASE WHEN status_to = 'Let' THEN 1 END) AS let FROM `crm_logs`
這會在我的數據庫中為我指定的所有術語提供正確的輸出,但現在我發現數據庫中除了上面指定的變數之外還有更多的狀態變數。所以我想要一種方法來擁有與此語句相同的功能,但使狀態變數動態化。
基本上,如果這是查詢,
SUM(CASE WHEN status_to = 'Draft' THEN 1 END) AS draft
則草稿的出現都應該是動態的。
有一種更簡單的方法可以做你想做的事——我昨晚在想這個——在這裡看我的第二把小提琴。
您可以執行以下操作(下面的所有程式碼都可以在此處的小提琴中找到):
CREATE TABLE test ( t_id INTEGER NOT NULL PRIMARY KEY, status_to VARCHAR (50) );
然後填充它:
INSERT INTO test VALUES (7, NULL), (8, 'Test_val_1'), (9, 'Test_val_2'), (3, 'Publish'), (4, 'Action'), (5, 'Sold'), (6, 'Let'), (10, 'Draft'), (11, 'Unpublish'), (12, 'Publish'), (13, 'Action'), (14, 'Sold'), (15, 'Let'), (26, 'Draft'), (16, 'Unpublish'), (17, 'Publish'), (18, 'Action'), (19, 'Sold'), (20, 'Let'), (27, 'Draft'), (21, 'Unpublish'), (22, 'Publish'), (23, 'Action'), (24, 'Sold'), (25, 'Let'), (1, 'Draft'), (2, 'Unpublish'), (29, NULL), (30, NULL), (35, 'Test_val_1'), (31, 'Test_val_2'), (45, 'Single_1'), (46, 'Single_2');
請注意,我添加了 2 個單例值 (
Single_1
和Single_2
) 來檢查如何計算DISTINCT
表中具有大於 1 條記錄的值……使用“經典”SQL 更困難 - 使用視窗函式,它是很容易。新的“簡單”查詢是:
SELECT COUNT(DISTINCT(status_to)) AS "Unique count" FROM test;
(新)結果:
Unique count 10
注意這個新查詢和我的舊查詢的小提琴底部結果的極端差異!
EXPLAIN ANALYZE
此查詢展示瞭如何輕鬆挑選出具有多個記錄的
DISINCT
值:status_to
SELECT COUNT(rn) OVER (PARTITION BY rn) AS "Unique count" FROM ( SELECT t_id, status_to, ROW_NUMBER() OVER (PARTITION BY status_to ORDER BY status_to) AS rn FROM test WHERE status_to IS NOT NULL ORDER BY status_to, t_id ) AS tab WHERE rn > 1 GROUP BY status_to ORDER BY status_to LIMIT 1;
結果:
Unique count 8
8 = 10(總計)減去 2 個單例!
我還包括了這個 SQL——它可以讓你輕鬆地(手動)計算
UNIQUE
條目的數量。SELECT status_to, MAX(rn) FROM ( SELECT t_id, status_to, ROW_NUMBER() OVER (PARTITION BY status_to ORDER BY status_to) AS rn FROM test WHERE status_to IS NOT NULL ORDER BY status_to, t_id ) AS tab WHERE rn > 1 <<==== **** GROUP BY status_to ORDER BY status_to;
結果:
status_to MAX(rn) Action 4 Draft 4 Let 4 Publish 4 Sold 4 Test_val_1 2 Test_val_2 2 Unpublish 4 8 rows <<---- note 8 rows!
我在第二個小提琴中留下了更多的片段——如果你真的想了解 SQL,我會邀請你看看舊的和新的,並嘗試使用 PostgreSQL 執行程式碼——這很有趣!
DISTINCT
最後,如果您希望使用所有值及其s動態構造一行(根據您的原始問題)COUNT()
,那麼您可以使用某種形式的RECURSIVE CTE
- 但這是另一個問題!