【问题标题】: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 会让它变得很棒。

标签: sql sql-server aggregate-functions distinct string-aggregation


【解决方案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
      
            
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-14
        • 2023-04-10
        • 2021-04-27
        • 2012-05-15
        • 1970-01-01
        相关资源
        最近更新 更多