简体   繁体   English

如何在SQL中透视该表

[英]How to pivot this table in SQL

I came across this issue when trying to make use of this "active users" table from Microsoft NAV. 尝试使用Microsoft NAV中的“活动用户”表时遇到了此问题。 What I got asked to do is a Dashboard in Power BI or other tool that will allow the company I work for to understand how many users are active on the NAV system at any point in time. 我被要求做的是Power BI中的仪表板或其他工具,该工具将使我工作的公司可以随时了解有多少用户在NAV系统上处于活动状态。 I found a DAX formula in Power BI that could do the trick - but it requires the following table transformation: 我在Power BI中发现了DAX公式可以解决问题-但它需要进行以下表转换:

I am trying to do this in SQL Management Studio: 我正在尝试在SQL Management Studio中执行此操作:

My SQL Server is Microsoft SQL Azure (RTM) - 12. 我的SQL Server是Microsoft SQL Azure(RTM)-12。

How could I pivot this NAV table below with the following structure knowing that Session ID might repeat further down the line? 我如何使用下面的结构来透视下面的NAV表,从而知道会话ID可能会重复下去?

Session ID  |    Event Datetime       | Event Type
350              2017-07-01 01:00       Logon
350              2017-08-01 02:00       Logoff
351              2017-07-01 02:00       Logon
351              2017-08-01 03:00       Logoff
350              2017-09-01 01:00       Logon
350              2017-09-01 02:00       Logoff

The final result would be each Session ID against their Logon and Logoff time (allowing duplicates if Session ID repeats like in this example) 最终结果将是每个会话ID对应其登录和注销时间(如果像本示例一样重复会话ID,则允许重复)

Thanks a lot in advance. 非常感谢。

Best 最好

Andre 安德烈

This is TSQL code and will run on an Azure database. 这是TSQL代码,将在Azure数据库上运行。 I think this will get you the results you are looking for. 我认为这将为您提供所需的结果。

DECLARE @ActiveUsersLog AS TABLE
      (
          sessionId     INT
         ,EventDateTime DATETIME
         ,EventType     VARCHAR(50)
      );

INSERT INTO @ActiveUsersLog
     (
         sessionId
        ,EventDateTime
        ,EventType
     )
VALUES
     (350, '2017-07-01 01:00', 'Logon')
    ,(350, '2017-08-01 02:00', 'Logoff')
    ,(351, '2017-07-01 02:00', 'Logon')
    ,(351, '2017-08-01 03:00', 'Logoff')
    ,(350, '2017-09-01 01:00', 'Logon')
    ,(350, '2017-09-01 02:00', 'Logoff');

WITH cte_logon
    AS (
           SELECT aul.sessionId
                 ,aul.EventDateTime
                 ,seq = RANK() OVER (PARTITION BY aul.sessionId ORDER BY aul.EventDateTime)
             FROM @ActiveUsersLog AS aul
            WHERE aul.EventType = 'Logon'
       )
    ,cte_logoff
    AS (
           SELECT aul.sessionId
                 ,aul.EventDateTime
                 ,seq = RANK() OVER (PARTITION BY aul.sessionId ORDER BY aul.EventDateTime)
             FROM @ActiveUsersLog AS aul
            WHERE aul.EventType = 'Logoff'
       )
SELECT o.sessionId
      ,LogonTime = o.EventDateTime
      ,LogoffTime = f.EventDateTime
  FROM cte_logon AS o
      LEFT OUTER JOIN cte_logoff AS f
          ON o.sessionId = f.sessionId
             AND o.seq = f.seq;

If you are only looking for active users then you would add this where clause: (make sure to remove the semicolon at the end of the code above before adding a where clause) 如果您只寻找活动用户,则可以添加以下where子句:(确保在添加where子句之前,在上述代码的末尾删除分号)

where f.EventDateTime is null

Without knowing the flavour of SQL, I can only give you basic advice. 在不了解SQL风格的情况下,我只能提供基本建议。

By performing an inner join with both sides lining to the same table (aliasing appropriately) matching on the session_id of both sides, you can then filter Event Type on one of the aliased tables to equal Logon and Event Type on the other aliased table to match Logoff . 通过执行内连接双方衬同一个表(混叠适当地)上的匹配session_id两侧的,然后可以过滤Event Type的混叠的表中的一个等于LogonEvent Type对其他别名的表,以匹配Logoff

This method should work on just about any form of SQL I've used, as it's core functionality of SQL. 由于该方法是SQL的核心功能,因此它几乎可以在我使用的任何形式的SQL上都可以使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM