2015-05-29 57 views
0

這裏的不同條件和總數計算是一個樣表我有SQL查詢來找到在同一查詢

Logs 
user_id, session_id, search_query, action 
1, 100, dog, A 
1, 100, dog, B 
2, 101, cat, A 
3, 102, ball, A 
3, 102, ball, B 
3, 102, kite, A 
4, 103, ball, A 
5, 104, cat, A 

其中 錯過=爲同一USER_ID和相同的會話ID,如果動作A其次是行動B,它被稱爲小姐。
注意:只有在行動A發生後纔可能發生行動B.

我能夠找到所有用戶和會話中每個唯一search_query的未命中數。

SELECT l1.search_query, count(l1.*) as misses 
FROM logs l1 
WHERE NOT EXISTS 
    (SELECT NULL FROM logs l2 
    WHERE l1.user_id = l2.user_id 
    AND l1.session_id = l2.session_id 
    AND l1.session_id != '' 
    AND l2.action = 'B' 
    AND l1.action = 'A') 
AND l1.action='A' 
AND l1.search_query != '' 
GROUP BY v1.search_query 
order by misses desc; 

我想爲每個唯一的search_query找到miss_percentage =(失誤次數/總行數)* 100的值。我無法弄清楚如何在一個查詢中找到一個條件計數並且沒有這個條件的計數。任何幫助都會很棒。

expected output: 
cat 100 
kite 100 
ball 50 

回答

0

一種方式來做到這一點是在EXISTS進入計數

SELECT l1.search_query, count(case when NOT EXISTS 
    (SELECT 1 FROM logs l2 
    WHERE l1.user_id = l2.user_id 
    AND l1.session_id = l2.session_id 
    AND l1.search_query = l2.search_query 
    AND l2.action = 'B' 
    AND l1.action = 'A') then 1 else null end 
)*100.0/count(*) as misses 
FROM logs l1 
WHERE l1.action='A' 
AND l1.search_query != '' 
GROUP BY l1.search_query 
order by misses desc; 

這將產生預期的效果,但如果被發現也沒有零失誤。這可以通過HAVING子句或後處理來刪除。

注意我還添加了缺失的子句l1.search_query = l2.search_query,因爲否則它會將風箏計數成功,因爲在同一個會話中有一行B。

+0

對不起,忘了提及此之前。我在亞馬遜紅移表中運行此查詢。我收到以下錯誤。 '執行SQL命令時發生錯誤: SELECT l1.search_query,count(NOT EXISTS時的情況) (SELECT 1 FROM logs l2 WHERE l1.user_id = 1 ... 錯誤:此類型的相關子查詢模式不是支持由於內部錯誤[SQL狀態= XX000]' – srini

-1

你可以總是創建兩個查詢,並將它們合併爲一個連接。然後,您可以在橋接(或加入)SQL語句中執行計算。

在MS-SQL兼容SQL這將是:

SELECT ActiontypeA,countedA,isNull(countedB,0) as countedB, 
    (countedA-isNull(countedB,0))*100/CountedA as missed 
    FROM (SELECT search_query as actionTypeA, count(*) as countedA 
      FROM logs WHERE Action='A' GROUP BY actionType 
     ) as TpA 
    LEFT JOIN 
     (SELECT search_query as actionTypeB, count(*) as countedB 
      FROM logs WHERE Action='B' GROUP BY actionType 
     ) as TpB 
ON TpA.ActionTypeA = TpB.ActiontypeB 

LEFT JOIN需要從「A」的結果選擇的所有活動(SEARCH_QUERY),並將其從「B」加入到只有那些結果在B可用。 由於這是非常基本的SQL(並且通過SQL引擎進行了很好的優化),我建議儘可能防止WHERE EXISTSIsNull()函數是一個MS-SQL函數,用於將NULL值強制爲可用於計算的int(0)值。

最後,你可以過濾對

WHERE missed>0 

得到最終的結果。

+0

如果問題是關於PostgreSQL,爲什麼要放一個MSSQL解決方案? – Patrick

+0

SQL跨引擎非常兼容。這個答案有助於跨系統的SQL概念。我只能在MS-SQL上測試解決方案。我對這個問題的投票並不滿意...... –

+0

SQL是一種標準,MSSQL因其背離而遠近聞名,遠遠超過PostgreSQL。後者沒有用於指定目的的'isNull()'函數,但使用'coalesce()'。而且你的代碼有錯誤,無論你在PostgreSQL或MSSQL中運行它。 downvote是一個不適當的答案。 – Patrick

0

我想你只需要在這裏使用case語句。如果我已經正確理解你的問題,那麼解決方案將是這樣的 -

WITH summary 
AS (
    SELECT user_id 
     ,session_id 
     ,search_query 
     ,count(1) AS total_views 
     ,sum(CASE 
       WHEN action = 'A' 
        THEN 1 
       ELSE 0 
       END) AS action_a 
     ,sum(CASE 
       WHEN action = 'B' 
        THEN 1 
       ELSE 0 
       END) AS action_b 
    FROM logs l 
    GROUP BY user_id 
     ,session_id 
     ,search_query 
    ) 
SELECT search_query 
    ,(sum(action_a - action_b)/sum(action_a)) * 100 AS miss_percentage 
FROM summary 
GROUP BY search_query;