SQL Server: запрос JOIN возвращает слишком много строк - PullRequest
0 голосов
/ 12 июня 2019

У меня проблемы с запросом на соединение, возвращающим дубликаты записей, и я надеюсь, что кто-то может помочь мне выяснить, что происходит.

Я просмотрел подобные посты здесь и уточнил свой запросв некоторой степени основанный на этой информации, но я не очень разбираюсь в SQL и просто не могу найти правильную комбинацию.

В основном у меня есть 2 таблицы, Attrib и AgentLV (Live).

Таблица Attrib (на самом деле таблица Agent_Attribute) содержит информацию о том, к каким группам принадлежит агент. Агент идентифицируется по столбцу Attrib.SkillTargetID, а Attrib.AttributeID обозначает конкретную интересующую нас группу.in (агент может принадлежать нескольким группам)

Таблица 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

, хотя я пытаюсьчтобы вернуть 1 строку из AgentLV, возвращая 'TOP 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 строк, чтобы она была полезной.

1 Ответ

0 голосов
/ 12 июня 2019

Вы можете использовать или row_number() оконную функцию для генерации последовательности № за SkillTargetID

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...