【问题标题】:How to get some items and then remove duplicate items?如何获取一些项目,然后删除重复的项目?
【发布时间】:2020-04-17 16:36:12
【问题描述】:

我有一张类似下面的桌子。我想获取用户和角色每天的访问次数。

表格:

CREATE TABLE #TempUser
(
  [Id] int NULL,
  [Username] nvarchar(50) NULL
)

CREATE TABLE #TempRole
(
  [Id] int NULL,
  [Title] nvarchar(50) NULL
)

CREATE TABLE #TempUserRole
(
  [UserId] int NULL,
  [RoleId] int NULL,
  [LastDate] date NULL
)

数据:

INSERT INTO #TempUser([Id],[UserName])
VALUES
(1,'Marvin'),
(2,'Tom'),
(3,'Charli')

INSERT INTO #TempRole([Id],[Title])
VALUES
(1,'Admin'),
(2,'Manager'),
(3,'Guest')

INSERT INTO #TempUserRole([UserId],[RoleId],[LastDate])
VALUES
(1,1,'2019-02-03'),
(1,2,'2019-02-06'),
(1,2,'2019-02-03'),
(3,3,'2019-02-03'),
(3,1,'2019-02-02'),
(3,1,'2019-02-03'),
(2,1,'2019-02-05'),
(2,1,'2019-02-05'),
(3,1,'2019-02-03'),
(1,1,'2019-02-03'),
(2,1,'2019-02-06'),
(2,1,'2019-02-03'),
(1,1,'2019-02-03'),
(2,1,'2019-02-02'),
(1,1,'2019-02-03'),
(2,1,'2019-02-05'),
(1,1,'2019-02-05'),
(2,1,'2019-02-03')

如何获取具有相同“user”、“Role”、“Date”、“CounterOfDay”的用户列表的用户和角色每天的访问次数?我需要的输出应该是这样的:

UserName  Role    Date          CounterOfDay

Charli    Admin   2019-02-02    2

Tom       Admin   2019-02-02    2
...

【问题讨论】:

  • 这似乎是一个简单的JOINGROUP BY。你试过吗?
  • 我不想使用GROUP BY 并且无法删除重复项
  • GROUP BY 的替代方案是使用 COUNT(*) OVER (PARTION BY ....) 语法。

标签: sql sql-server


【解决方案1】:

这是您的答案,但请检查它可能存在的任何语法错误,因为我不经常为 SQL-Server 编写查询。

WITH counters AS (
   SELECT UserId, RoleId, LastDate, COUNT(*) AS CounterOfDay 
   FROM TempUserRole 
   GROUP BY UserId, RoleId, LastDate
)

SELECT 
   user.UserName
   , role.Title
   , counters.LastDate
   , counters.CounterOfDay
FROM counters
JOIN TempRole AS role ON counters.RoleId = TempRole.Id
JOIN TempUser AS user ON counters.UserId = TempUser.Id

我认为阅读起来很不错,而且它应该比先进行连接更高效。

【讨论】:

  • 这是哪个数据库系统? Group By 1, 2, 3 不起作用,而且没有设置别名。不过,你的方法很好。
  • BigQuery 的标准 SQL。感谢您指出别名,完全错过了那里的标记。将对其进行编辑以包含您的笔记
【解决方案2】:

您可以尝试以下方法。这是demo

with cte as
(
  select
    userName,
    title,
    lastDate,
    count(*) as total
  from tempUserRole tur
  join tempUser tu
  on tur.userId = tu.id

  join tempRole tr
  on tur.roleId = tr.id

  group by
    userName,
    title,
    lastDate
),
rnk as  
(
  select 
      *,
      dense_rank() over (order by lastDate, title, total) as rnk
  from cte
),
cnt as
( 
  select
    *,
    count(*) over (partition by rnk) as ttl
  from rnk
)


select
    userName,
    title,
    lastDate,
    total
from cnt
where ttl > 1

【讨论】:

    猜你喜欢
    • 2021-08-28
    • 1970-01-01
    • 1970-01-01
    • 2016-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-22
    相关资源
    最近更新 更多