sql-server - SQL Server:JOIN 查询返回太多行
问题描述
我在连接查询返回重复记录时遇到问题,我希望有人能帮我弄清楚发生了什么。
我在这里查看了类似的帖子,并根据这些信息对我的查询进行了一些改进,但我并不是真正的 SQL 专家,我似乎无法获得正确的组合。
基本上我有 2 张桌子Attrib
和AgentLV
(Live)。
表Attrib
(真正的表Agent_Attribute
)包含有关代理所属组的信息 - 代理由 column 标识Attrib.SkillTargetID
,并Attrib.AttributeID
标识我们感兴趣的特定组(一个代理可以属于多个组)
表 2 包含与特定代理相关的事件。代理标识符是AgentLV.SkillTargetID
。特定代理的代理事件可以从代理所属的任何组发生,并且信息包括时间戳。
我试图提取的信息是:对于特定组中的代理,该代理的最新事件是什么。
如果事件与被查询的组或代理所属的另一个组相关联,则无关紧要。我只关心那个组的特工最近在做什么。
因此,对于特定组,组中的每个代理将有 1 行,对于此查询:
SELECT TOP 100
Attrib.SkillTargetID AS AttribSKID,
Attrib.AttributeID,
[AttributeValue]
FROM
Agent_Attribute Attrib --returns 1 STID by itself
WHERE
Attrib.AttributeID = 5068
ORDER BY
AttributeValue DESC
像这样:
6221 5068 5
6210 5068 5
6197 5068 5
6192 5068 5
6184 5068 5
但是对于 AgentLV 表,会有多行。
因此,即对于代理 6221,查询返回多个事件
SELECT TOP 5
AgentLV.SkillTargetID AS AgntLvSKID,
AgentLV.DateTime,
AgentLV.Event
FROM
[prod_awdb].[dbo].[Agent_Event_Detail] AgentLV
WHERE
AgentLV.SkillTargetID = 6221
AND AgentLV.[DateTime] > GETDATE() - 1
输出:
6221 2019-06-11 07:55:49.000 1
6221 2019-06-11 07:55:53.000 3
6221 2019-06-11 11:30:00.000 3
6221 2019-06-11 11:45:00.000 3
6221 2019-06-11 11:46:20.000 3
我的目标是为组中的每个用户构建一个返回 1 行的查询 - 带有最新的时间戳。所以对于组 5068,代理 6221 应该只返回
Attrib.SkillTargetID AgentLV.SillTargetID Attrip.AttributeID AttribValue AgentLV.DateTime AgetnLV.Event
6221 6221 5068 5 2019-06-11:46 3
为此(以最简单的形式),我尝试了以下查询:
SELECT TOP 100
Attrib.SkillTargetID AS AttribSKID,
AgentLV.SkillTargetID AS AgntLvSKID,
Attrib.AttributeID,
[AttributeValue],
AgentLV.DateTime
FROM
Agent_Attribute Attrib --returns 1 STID by itself
INNER JOIN
[prod_awdb].[dbo].[Agent_Event_Detail] AgentLV
ON Attrib.SkillTargetID = (SELECT TOP 1 AgentLV.SkillTargetID
FROM [prod_awdb].[dbo].[Agent_Event_Detail] AgentLV
WHERE AgentLV.SkillTargetID = Attrib.SkillTargetID
ORDER BY DateTime DESC)
WHERE
Attrib.AttributeID = 5068
AND AgentLV.DateTime > GETDATE() - 1
ORDER BY
AttributeValue DESC
但即使我试图AgentLV
通过返回“TOP 1”来返回 1 行,但我最终会为每个代理返回很多行,如下所示:
AttribSKID AgntLvSKID AttributeID AttributeValue DateTime
6192 5461 5068 5 2019-06-11 21:01:12.007 11:59:08.050
6184 5461 5068 5 2019-06-11 21:01:12.007 11:59:08.050
6221 5461 5068 5 2019-06-11 21:01:12.007 11:59:08.050
6184 5461 5068 5 2019-06-11 21:01:12.000 11:59:08.000
6221 5461 5068 5 2019-06-11 21:01:12.000 11:59:08.000
6192 5461 5068 5 2019-06-11 21:01:12.000 11:59:08.000
6192 6758 5068 5 2019-06-11 21:01:05.007 18:52:13.077
6184 6758 5068 5 2019-06-11 21:01:05.007 18:52:13.077
6221 6758 5068 5 2019-06-11 21:01:05.007 18:52:13.077
6192 5798 5068 5 2019-06-11 21:01:02.007 11:58:21.550
6184 5798 5068 5 2019-06-11 21:01:02.007 11:58:21.550
6221 5798 5068 5 2019-06-11 21:01:02.007 11:58:21.550
6192 6419 5068 5 2019-06-11 21:01:01.007 10:02:28.563
6184 6419 5068 5 2019-06-11 21:01:01.007 10:02:28.563
6221 6419 5068 5 2019-06-11 21:01:01.007 10:02:28.563
我也尝试将第一行更改为
SELECT Distinct TOP 100
谁能告诉我我做错了什么?
松鼠,这是我试过的修改版本,你的查询:
SELECT *
FROM (
SELECT rn = row_number() over (partition by Attrib.SkillTargetID
order by AgentLV.DateTime desc),
Attrib.SkillTargetID --AS AttribSKID
,AgentLV.SkillTargetID AS AgntLvSKID
,Attrib.AttributeID
--,Attrib.Description
,[AttributeValue]
,AgentLV.Duration
,AgentLV.DateTime
--,AgentLV.LoginDateTime
FROM Agent_Attribute Attrib
INNER JOIN [prod_awdb].[dbo].[Agent_Event_Detail] AgentLV
ON Attrib.SkillTargetID = AgentLV.SkillTargetID
) AS D
WHERE D.rn = 1
AND D.AttributeID>5067 AND D.AttributeID<5071
AND D.[DateTime] > GetDate()-1 --specify fraction of day
order by D.AttributeID
我希望得到如下所示的返回数据:
AttribSKID AgntLvSKID AttributeID AttributeValue DateTime
6197 6197 5068 5 2019-6-12 8:40
6183 6183 5068 5 2019-6-12 8:40
6221 6221 5068 5 2019-6-12 8:39
6192 6192 5068 5 2019-6-12 8:39
6184 6184 5068 5 2019-6-12 8:40
6210 6210 5068 5 2019-6-12 8:40
实际上最终它会看起来像这样 - 但稍后会出现:
AttribSKID AgntLvSKID AgentDTStgsID DTsettings Attrib AttributeID AttributeValue AgentNm DN Duration DateTime LoginDateTime
6197 6417 5012 US.Dtsettings US.Attrib.Name 5068 5 US.NameHere 15551112222 185 2019-6-12 8:40 2019-6-12 8:15
即使是两个表的小测试数据提取也会非常大 - 有没有办法在这里附加文件?我找不到它。对于第二个表 Id 需要显示大约 500 行才能有用。
解决方案
您可以使用或row_number()
窗口函数生成一个序列 no perSkillTargetID
SELECT *
FROM (
SELECT rn = row_number() over (partition by Attrib.SkillTargetID
order by AgentLV.DateTime desc),
{other columns that you required}
FROM Agent_Attribute Attrib
INNER JOIN [prod_awdb].[dbo].[Agent_Event_Detail] AgentLV
ON Attrib.SkillTargetID = AgentLV.SkillTargetID
) AS D
WHERE D.rn = 1
推荐阅读
- html - IONIC :: 离子列表中数据与离子复选框的垂直对齐
- ios - PageViewController 在使用 segue 按下按钮后禁用 - Swift 4
- reactjs - 我应该更改哪些设置,以便在将 react 构建上传到主机后查看图像?
- java - 如何在java中使用递归实现背包问题
- powershell - PowerShell,从“Foreach”中的结果到日志文件的详细输出
- java - 为什么这个多线程程序会陷入无限循环?
- c# - 如何将 SQL Server 中的图像放入 Visual Studio PictureBox
- html - 为什么 div 的固定位置会破坏它在 HTML 和 CSS 中的前景
- r - 在 R 中创建 3 维表时遇到问题
- r - 将 14 位日期时间对象转换为 POSIXct