Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于最近日期sql的计数_Sql_Postgresql_Greatest N Per Group - Fatal编程技术网

基于最近日期sql的计数

基于最近日期sql的计数,sql,postgresql,greatest-n-per-group,Sql,Postgresql,Greatest N Per Group,我试图统计从他们注册到的任何设备进行交易的唯一用户 我的问题是: 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'

我试图统计从他们注册到的任何设备进行交易的唯一用户

我的问题是:

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); 
但是,在结果集中,我得到以下结果:

例如,我希望根据最新日期对用户ujvs24hxen9/abdallah进行计数,例如,仅在internetbanking中计数一次,而不在internetbanking和ios中计数一次

我该怎么做?我正在使用postgresql

谢谢

试试这个:

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)

我假设当你说“最新”时间时,你指的是最大时间,而不是最小时间。

你可以使用
行数
窗口功能只获取每个用户的最后一笔交易:

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

@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

使用PostgreSQL的
DISTINCT ON(username)
只为每个用户获取一条记录。使用
ORDER BY
子句首先获取每个用户所需的记录(即最新记录):

至于你自己的疑问:

  • 按xyz分组
    表示希望每个xyz有一个结果行。在查询中,您可以按前两列进行分组,这样就可以按用户和类型获得结果行。但您只希望每个用户有一个结果行。因此,在
    GROUPBY
    子句中使用type没有任何意义
  • DISTINCT
    从结果中删除重复的行。当您按用户和类型分组,并且选择了这两列时,不能有重复项;这两列已经使每一行变得不同,因此对这些行应用
    distinct
    是多余的
  • 而且,在任何地方,您都无法找到每个用户的最新时间,并使用它访问所需的记录。显然,这个查询无法工作

我想对用户名进行计数并按类型分组,此查询工作正常,但我无法按操作系统类型对用户名进行计数和分组。您可以根据上述查询的结果进行构建:
select type,count(*)from()x group by type
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;
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