按列分组并分布在多个分箱中的用户数量不同

时间:2017-11-13 10:30:34

标签: sql sql-server tsql

我有几个用户,每个用户都有一个他们所属的部门,以及一个整数,表示他们上次登录的时间(以天为单位)。 用户可以拥有多个部门。

我正在尝试按部门对用户进行分组,根据他们登录的时间将它们垂直分布在三个分箱中,然后对它们进行唯一计数。 如果一个用户属于多个部门,我只想计算一次,那么他们被计算在哪个部门并不重要。

在我目前的解决方案中,有几个部门的用户会被计算一次 每个部门,根据我的解决方案,有道理,但不是我想要的。 如果我尝试一个非常计数,它返回相同,因为每一行都是唯一的。

我正在使用MsSql Fiddle示例,只是我添加了一个DaysSinceLastLogin (int)列,表示用户上次登录的时间。 取消注释第一个sql块以查看6个用户以及他们所属的部门。 Fiddle here

3 个答案:

答案 0 :(得分:2)

作为变体,您可以使用子查询

SELECT
  MaxDepartment, 
  COUNT(case when MaxDaysSinceLastLogin < 10 then 1 end) as 'Last Login within 10 days', 
  COUNT(case when MaxDaysSinceLastLogin > 10 and  MaxDaysSinceLastLogin <= 20 then 1 end) as 'Last Login within 10-20 days', 
  COUNT(case when MaxDaysSinceLastLogin > 20 then 1 end) 'Last Login more then 20 days'
FROM
  (
    SELECT
      [User],
      -- any department
      MAX([Department]) MaxDepartment,
      -- max of days
      MAX([DaysSinceLastLogin]) MaxDaysSinceLastLogin
    FROM yourtable
    GROUP BY [User]
  ) q
GROUP BY MaxDepartment

我希望我能正确理解你。

答案 1 :(得分:2)

试试这个:

 WITH DataSource AS
 (
     SELECT *
          ,ROW_NUMBER() OVER (PARTITION BY [User] ORDER BY (SELECT 1))   AS [RowID]
     FROM yourtable
)
select Department, 
COUNT(case when DaysSinceLastLogin < 10 then 1 end) as 'Last Login within 10 days', 
COUNT(case when DaysSinceLastLogin > 10 and  DaysSinceLastLogin <= 20 then 1 end) as 'Last Login within 10-20 days', 
COUNT(case when DaysSinceLastLogin > 20  then 1 end) 'Last Login more then 20 days'
FROM DataSource
WHERE [RowID] = 1
GROUP BY Department;

我们的想法是使用ROW_NUMBER为特定用户的每个部门设置ID。然后只为第一个部门获取数据。

答案 2 :(得分:0)

如果他们被计算在哪个部门无关紧要,您可以更改CTE内的部门并使用您的查询:

;WITH CTE AS (
SELECT DISTINCT
  [User]
  ,CASE WHEN
    department = (SELECT top 1 department FROM yourtable y WHERE [User] = t.[User]) THEN department
    ELSE (SELECT top 1 department FROM yourtable y WHERE [User] = t.[User])
  END AS department
  ,[DaysSinceLastLogin]
FROM yourtable t
)
select Department, 
COUNT(case when DaysSinceLastLogin < 10 then 1 end) as 'Last Login within 10 days', 
COUNT(case when DaysSinceLastLogin > 10 and  DaysSinceLastLogin <= 20 then 1 end) as 'Last Login within 10-20 days', 
COUNT(case when DaysSinceLastLogin > 20  then 1 end) 'Last Login more then 20 days'
FROM CTE
GROUP BY Department

另外HERE