2017-02-27 60 views
2

我正在嘗試計算從註冊到的任何設備進行交易的唯一用戶。根據最近的日期進行計數sql

這裏是我的查詢:

select Distinct 
    username , 
    case 
     when user_agent like '%Android%' then 'Android' 
     when user_agent like '%iPhone%' OR user_agent like '%Iphone%' then  'IOS' 
     else 'Internet Banking' 
    end as type, 
    min(time) 
from 
    activeUsers 
group by 
    (1, 2); 

然而,在結果集,我得到這樣的:根據最新計計數

Image Showing query results

我想例如用戶ujvs24hxen9 /阿卜杜拉日期,例如僅在互聯網銀行中計算一次,而不在互聯網銀行和ios中計數。

我該怎麼做?我正在使用postgresql

謝謝!

回答

1

使用PostgreSQL的DISTINCT ON (username)每個用戶只能得到一條記錄。使用ORDER BY條款,每位使用者(即最新的)第一個需要的記錄:

select distinct on (username) 
    username, 
    case when user_agent like '%Android%' then 'Android' 
     when user_agent like '%iPhone%' 
     or user_agent like '%Iphone%' then 'IOS' 
     else 'Internet Banking' 
    end as type, 
    time 
from activeusers 
order by username, time desc; 

至於自己的查詢:

  • GROUP BY xyz意味着你要每一個xyz的結果行。在您的查詢中,您將按前兩列進行分組,以便您爲每個用戶和類型獲取結果行。但是你只需要每個用戶的結果行。因此輸入你的GROUP BY條款是沒有意義的。
  • DISTINCT從結果中刪除重複的行。當你按用戶和類型進行分組並且這兩列都被選中時,不會有重複;這兩列使每一行都已經不同,因此在這些行上應用DISTINCT是多餘的。
  • 而且,您甚至無法找到每個用戶的最新時間,並使用它訪問所需的記錄。所以顯然這個查詢不能工作。
+0

我想按類型統計的用戶名和他們組,這個查詢工作正常,但我不能指望通過操作系統類型用戶名和他們組 –

+0

您可以在上面查詢的結果建立:'選擇類型,計數( *)來自()x按類型分組;' –

1

試試這個:

select Distinct username , 
Case When user_agent like '%Android%' then 'Android' 
when user_agent like '%iPhone%' OR user_agent like '%Iphone%' then  'IOS' 
else 'Internet Banking' 
END as type , time 
from activeUsers a1 
where time = (select max(time) from activeUsers a2 where a1.username = a2.username) 

當你說「最新的時間,你的意思是沒有最大最小時間我假設。

0

您可以使用row_number窗函數只得到每個用戶的最後一筆交易:

SELECT username, type 
FROM (SELECT username , 
       CASE WHEN user_agent LIKE '%Android%' THEN 'Android' 
        WHEN user_agent LIKE '%iPhone%' OR 
         user_agent LIKE '%Iphone%' THEN 'IOS' 
        ELSE 'Internet Banking' 
     END AS type, 
     time 
     ROW_NUMBER() OVER (PARTITION BY username ORDER BY time DESC) AS rn 
FROM activeUsers) t 
WHERE rn = 1 
0

由@Mureinik給出的答案另一種方法是使用子查詢來識別最新的時間爲每個用戶,然後使用它將原始表限制爲結果集中實際需要的記錄。

WITH cte AS (
    SELECT username, MAX(time) AS max_time 
    FROM activeUsers 
    GROUP BY username 
) 

SELECT t1.username, 
     CASE WHEN t1.user_agent LIKE '%Android%' THEN 'Android' 
      WHEN t1.user_agent LIKE '%iPhone%' OR t1.user_agent LIKE '%Iphone%' THEN 'IOS' 
      ELSE 'Internet Banking' 
     END AS type 
FROM activeUsers t1 
INNER JOIN cte t2 
    ON t1.username = t2.username AND 
     t1.time  = t2.max_time 
1
select distinct on (username) 
    username, 
    case 
     when user_agent like '%Android%' then 'Android' 
     when user_agent like '%iPhone%' OR user_agent like '%Iphone%' then 'IOS' 
     else 'Internet Banking' 
    end as type 
    time 
from activeUsers 
order by username, time desc