查询以查找要聚合的不同字符串

Posted

技术标签:

【中文标题】查询以查找要聚合的不同字符串【英文标题】:Query to find distinct string to agregate 【发布时间】:2021-04-01 20:59:54 【问题描述】:

我有一个名为logoninfo 的数据库表。下面是架构。

   Record ID|User ID | Computer ID |LOGON_TIME|LOGOFF_TIME

如果注销时间为 0,则用户当前已登录计算机。 用户名在名为“user”的单独表中,带有架构

   user id  | user name 

计算机名称在名为“计算机”的单独表中,带有架构

    computer id | computer name 

我需要一份报告,其中包含用户名及其对应的当前登录计算机(以逗号分隔)

        user name | computer names

我使用了以下查询,但在某些情况下会导致重复的计算机(同一台计算机显示不止一次)。

select user.name as USER_NAME,
    userLogon."comps" as COMPUTERS
from user
    inner join (
        select user_id as "user_resource",
            string_agg(compRes.name, ' ,') as "comps"
        from logoninfo
            inner join computer compRes on logoninfo.computer_id = compRes.computer_id
        where logoninfo.logoff_time = 0
        group by logoninfo.user_id
    ) userLogon on userLogon."user_resource" = user.user_id

所以我尝试将distinct 添加到string_agg 函数中,但是在SQL Server 中是不可能的。

请帮我查询所需的报告。

提前致谢。

【问题讨论】:

样本数据和预期结果会让这一点更清楚。 DDL+DML 会让它变得很棒。 【参考方案1】:

我会使用相关子查询或横向连接:

select u.*, c.*
from users u
cross apply (
    select string_agg(name) as all_computers
    from (
        select distinct c.name
        from computer c
        inner join logoninfo li on li.computer_id = c.computer_id
        where li.user_id = u.user_id and li.logoff_time = 0
    ) c
) c

【讨论】:

【参考方案2】:

我是这样做的。可以去掉#符号,表示我用了临时表。

SELECT u.name as [USER_NAME]
     , l.comps as [COMPUTERS]
FROM #user u
OUTER APPLY (
  SELECT STRING_AGG(c.name, ', ') as [comps]
  FROM (
    SELECT c.name
    FROM #logoninfo l
    JOIN #computer c ON l.computer_id = c.computer_id
    WHERE l.user_id = u.user_id
      AND l.logoff_time = 0
    GROUP BY c.name
  ) c
) l

结果是:

【讨论】:

【参考方案3】:

这是一种方法。

使用 string_agg 进行早期过滤和聚合

select userLogon.user_resource
         , string_agg(compRes.name, ' ,') as concat_computer
    from (
          select distinct 
                  user_id as "user_resource",
                  compRes.name as "comps"
            from logoninfo
            join computer compRes 
              on logoninfo.computer_id = compRes.computer_id
            join user us
              on logonginfo.user_id=us.user_id
            where logoninfo.logoff_time = 0
          ) userLogon
  group by userLogon.user_resource

      

【讨论】:

以上是关于查询以查找要聚合的不同字符串的主要内容,如果未能解决你的问题,请参考以下文章

S1/C#语言和数据库技术基础/10-模糊查询和聚合函数

如何查询我的所有视图设计以查找 SQL Server 中的特定字符串?

为访问查询创建自定义聚合函数

如何在mongodb聚合中查找搜索字符串的出现次数?

连接两个表的字符串的聚合函数?

SQL 查询以查找遵循特定模式的字符串