如何根据最大计数选择行?(使用标准sql)

如何根据最大计数选择行?(使用标准sql),sql,ms-access,Sql,Ms Access,我有一张桌子: 计算机ID、用户ID、登录数据 我需要一个select语句,它返回: 计算机ID、用户ID、登录帐户 对于所有计算机,但对于每台计算机,仅显示最常登录到该计算机的一个用户。如果有一个平局,我想我只想随便挑选一个用户…所以这似乎表明我需要一个排名前1的地方 这是在ms access中,因此无法使用特定于供应商的功能 JBrooks答案的解决方案 要处理>1个用户可能拥有给定计算机的相同登录帐户的情况,我所能想到的就是将另一个选择围绕在这一点上,选择MaxUserID…..所以基本上

我有一张桌子:

计算机ID、用户ID、登录数据

我需要一个select语句,它返回: 计算机ID、用户ID、登录帐户

对于所有计算机,但对于每台计算机,仅显示最常登录到该计算机的一个用户。如果有一个平局,我想我只想随便挑选一个用户…所以这似乎表明我需要一个排名前1的地方

这是在ms access中,因此无法使用特定于供应商的功能

JBrooks答案的解决方案 要处理>1个用户可能拥有给定计算机的相同登录帐户的情况,我所能想到的就是将另一个选择围绕在这一点上,选择MaxUserID…..所以基本上您只是随意选择其中一个。这就是我在本例中所做的,在本例中,我将撤回最近的用户,而不是最活跃的用户:

Select ComputerID, Max(xUserID) As UserID, MaxLoginDate
FROM
(
SELECT main.ComputerID, main.UserID as xUserID, main.MaxLoginDate
FROM [select ComputerID, UserID, Max(LoginDate) as MaxLoginDate
    from ComputerLoginHistory
    group by ComputerID, UserID]. AS main 
     INNER JOIN [select ComputerID, Max(MaxLoginDate) As MaxLogin
                            from 
                                    (select ComputerID, UserID, Max(LoginDate) as MaxLoginDate
                                     from ComputerLoginHistory
                                     group by ComputerID, UserID) as Counts
                            group by ComputerID]. AS maxes ON (main.MaxLoginDate = maxes.MaxLogin) AND (main.ComputerID = maxes.ComputerID)
)
GROUP BY ComputerID, MaxLoginDate
ORDER BY ComputerID

在MS Access中,我将编写两个三个查询并调用第一个查询中的第二个查询。第一个查询只需进行计数,下一个查询将找到第一个查询的最大值。将前两个查询合并在一起后,第三个查询将引用第一个查询中的用户ID

例如:

qryCountQuery:

qryMaxQuery:

qryCountMaxQueryCombined:

注意:如果您有最多登录到一台电脑的用户,则这台电脑将与两个用户同时出现两次。您可以在另一个查询中加入一个UNIQUE或第一个聚合调用。这取决于每个计算机ID是否绝对必须只有一个结果

注2:在另一个系统(如MySQL)中,我可能会使用嵌套查询,但我更喜欢在Access中将其分开

注3:我忘了这个问题在访问中很难解决。我很高兴我测试了我的代码

MS-SQL,不确定这在Access中是否有效

尝试此示例的一些变体:

SELECT UserId, MAX(COUNT(*)) as "HighestLogin"
FROM YOURTABLE
GROUP BY ComputerId;

如果您想要每个计算机Id及其顶级用户的列表,它将类似于:

select main.*
from (select ComputerID, UserID, count(1) as cnt
    from logTable
    group by ComputerID, UserID) as main
    inner join (select ComputerID, max(cnt) maxCnt
                from (select ComputerID, UserID, count(1) as cnt
                    from logTable
                    group by ComputerID, UserID) as Counts) 
                as maxes
on main.ComputerID = maxes.ComputerID
and main.cnt = maxes.maxCnt

您能在Access数据库上检查一下吗:

select ComputerID, UserID, count(*) as LoginCount
from t2  parent_table
group by ComputerID, UserID
having count(*) = (select max(count(*) ) from t2 
       where ComputerID = parent_table.ComputerID group by ComputerID, UserID)
order by ComputerID, UserID

不确定这在MS ACCESS中是否可用,但在SQL Server 05和08中肯定可用,因此您必须对此进行调查

您可以使用方便的函数,该函数将允许您对数据子集进行分区并分配一个行号,然后您可以根据该行号限制返回的结果

DECLARE     @MaxResultsPerComputerID    INT
SELECT      @MaxResultsPerComputerID    = 3 -- assign the maximum number of results to bring back per computer

SELECT      *
FROM        (
            SELECT      ComputerID, 
                        UserID, 
                        LoginDate,
                        NumberOfTimesLoggedIn, -- Derive this value somehow (not sure what your db schema is)
                        ROW_NUMBER() OVER (PARTITION BY ComputerID ORDER BY NumberOfTimesLoggedIn) AS RowNumber -- the magic happens here
            FROM        SomeTable
            ) a
WHERE       RowNumber <= @MaxResultsPerComputerID

当有几个用户拥有相同数量的LoginCount时该怎么办?我用一个例子编辑了我的答案。我用access数据库中的一些样本数据对它进行了测试,它对我起了作用。如果两个用户登录到一台计算机的次数相同怎么办?我在最初的问题中对此sql进行了轻微的修改。该死。表达式中不能有聚合函数。错误3095这是Oracle,但我认为不是??这是sql server 05+,不确定它是否能在MS Access中工作。但是我不会删除它,因为它可能是一个有助于找到这个问题的答案。上面的行数可能对Oracle/SQL Server/DB2人群有用,但在Access、MySQL或PostgreSQL中没有用处来源:SQL Cookbook,p。330:我完全理解。我有时会在Access中这样做,但Access版本2002/XP喜欢终止我的SQL格式设置,使我的工作异常困难。TOP关键字不是Standard SQL。TOP是Standard Jet/ACE SQL。它至少从Jet 2.x开始得到支持。我甚至不知道术语标准SQL是什么意思。我所看到的只是一堆SQL方言,每个数据库引擎都略有不同。有SQL标准,但没有一个数据库引擎完全实现任何曾经存在的SQL标准。@David W.Fenton:标准SQL通常意味着ISO/ANSI SQL标准,所有SQL产品——甚至Jet 4.0时代的Access数据库引擎——都高度重视这些标准。另一方面,标准Jet/ACE SQL是您刚刚发明的一个短语;FWIW SQL-99标准的行数超过ORDER BY。。作为专有TOP N语法的替代语法。您是否尝试在Access中运行此SQL,即针对Jet/ACE数据存储?否。不过,这是非常通用的sql。临时表应该在Access中工作,但不确定是否创建/选择。@David W.Fenton:问题的标题状态,使用标准sql。如果您相信Access帮助(我不相信),Access数据库引擎确实支持创建临时表语法;
SELECT TOP 1 * FROM YOURTABLE ORDER BY LoginCount DESC
SELECT UserId, MAX(COUNT(*)) as "HighestLogin"
FROM YOURTABLE
GROUP BY ComputerId;
select main.*
from (select ComputerID, UserID, count(1) as cnt
    from logTable
    group by ComputerID, UserID) as main
    inner join (select ComputerID, max(cnt) maxCnt
                from (select ComputerID, UserID, count(1) as cnt
                    from logTable
                    group by ComputerID, UserID) as Counts) 
                as maxes
on main.ComputerID = maxes.ComputerID
and main.cnt = maxes.maxCnt
select ComputerID, UserID, count(*) as LoginCount
from t2  parent_table
group by ComputerID, UserID
having count(*) = (select max(count(*) ) from t2 
       where ComputerID = parent_table.ComputerID group by ComputerID, UserID)
order by ComputerID, UserID
create temporary table t select ComputerID, UserID, count(*) as LoginCount
from table group by ComputerID, UserID;

create temporary table m select ComputerID, max(LoginCount) as maxLoginCount
from t group by ComputerID;

select m.ComputerID, max(UserID) from m join t
on m.ComputerID = t.ComputerID and m.maxLoginCount = t.LoginCount
group by ComputerID;
DECLARE     @MaxResultsPerComputerID    INT
SELECT      @MaxResultsPerComputerID    = 3 -- assign the maximum number of results to bring back per computer

SELECT      *
FROM        (
            SELECT      ComputerID, 
                        UserID, 
                        LoginDate,
                        NumberOfTimesLoggedIn, -- Derive this value somehow (not sure what your db schema is)
                        ROW_NUMBER() OVER (PARTITION BY ComputerID ORDER BY NumberOfTimesLoggedIn) AS RowNumber -- the magic happens here
            FROM        SomeTable
            ) a
WHERE       RowNumber <= @MaxResultsPerComputerID