首页 > 解决方案 > 在外键上选择不同的,内连接另一个表

问题描述

基本上我想要做的是,选择用户做出的最后三个动作。但是 RelationId 上没有重复项,并且还有 innerjoin 权限,只是为了确保用户仍然有权执行相同的操作。

我唯一想要获得许可的是 RelationId。

没有重复我的意思是如果有两行具有相同 RelationId 的 Action 应该选择靠近顶部的那一行(按 TimeStamp 排序)。

到目前为止我想出了什么:

SELECT DISTINCT a.*, p.RelationId
FROM [Action] [a]
INNER JOIN [Permission] p 
  ON ([p].[RelationId] = [a].[RelationId] 
  AND [p].[RelationType] = [a].[RelationType] 
  AND [p].[UserId] = [a].[UserId] 
  AND [p].[Deleted] = 0)
WHERE [a].[ActionType] = 'Clicked' 
AND [a].[RelationType] = 'Direct' 
AND [a].[UserId] = 5 
AND [a].[Deleted] = 0
ORDER BY [a].[TimeStamp] DESC
OFFSET 0 ROWS
FETCH NEXT 3 ROWS ONLY

它只需要使用 OFFSET X ROWS 和 FETCH NEXT 3 ROWS 来进行分页

由于某种原因,这不起作用,因为我在 RelationId 上得到了重复项。没有错误。

示例数据:

action (
    id            INTEGER       PRIMARY KEY,
    ActionType    VARCHAR(50)   not null,
    RelationId    INTEGER       ForeignKey,
    Deleted       Bit           not null,
    TimeStamp     DATE          not null,
    UserId        INTEGER       ForeignKey
);

期望的结果:一个用户执行的 3 个最后操作,该用户对其具有不同的 RelationId 权限。

标签: sqlsql-serverinner-joindistinct

解决方案


根据您对每个用户最后 3 个的定义(如果最后 3 个,则每个关系 ID 不能是单行):

with data as (
  SELECT *, 
  row_number() over (partition by relationId order by [timeStamp] desc) as rNo
  from action 
  where [ActionType] = 'Clicked' AND 
        [RelationType] = 'Direct' AND 
        [UserId] = 5 AND 
        [Deleted] = 0
)
select a.id,a.ActionType,a.RelationId,a.Deleted,a.TimeStamp,a.UserId,
       p.RelationId as pRelId
FROM [data] [a]
INNER JOIN [Permission] p ON ([p].[RelationId] = [a].[RelationId] AND [p].[RelationType] = [a].[RelationType] AND [p].[UserId] = [a].[UserId]) 
WHERE p.[Deleted] = 0 and a.rNo <= 3
ORDER BY [a].[TimeStamp] DESC;

推荐阅读