Как сделать GROUP BY с INNER JOIN - PullRequest
0 голосов
/ 07 июля 2019

У меня небольшая проблема с GROUP BY и INNER JOIN.Я пытаюсь отработать часы в группе инцидентов по пользователям, чтобы убедиться, что этот пользователь более эффективен.

В данный момент я получаю только ошибку

'Колонка' XXX 'недопустим в списке выбора, потому что он не содержится ни в статистической функции, ни в предложении GROUP BY '

Я понимаю, что все поля в операторе SELECT обязательны в GROUP BY, но если яГруппа для всех этих полей, я не получаю, что я хочу.

Я думаю, что моя проблема в том, что я не правильно понимаю GROUP BY и INNER JOIN, поэтому я пытался выучить многовеб-сайты, но по крайней мере в данный момент я не вижу свою ошибку.

Вот мой код:

SELECT
  id_incident_project AS ID,
  i.title AS title,
  companyname as social_name,
  username as tech_name,
  ia.DESCRIPTION_TEXT as description,
  CONVERT(varchar, ia.ACTIONDATE, 101) as action_date,
  CAST(TIME as INT) as acting_time,
  CAST(actions_time as INT) AS total_time
FROM
  incident i
  INNER JOIN incident_0001 i1 ON i1.ID_INCIDENT = i.ID_INCIDENT
  INNER JOIN incident_action ia ON ia.ID_INCIDENT = i.ID_INCIDENT
  INNER JOIN agent a ON a.ID_AGENT = ia.ID_AGENT
  INNER JOIN username u on u.ID_USERNAME = a.ID_USERNAME
WHERE
  ia.ACTIONDATE BETWEEN '## START DATE (YYYYMMDD)##' AND '## END DATE (YYYYMMDD)##'
GROUP BY username

1 Ответ

1 голос
/ 08 июля 2019

Все столбцы в предложении SELECT, по которым вы не группируете, должны проходить через агрегатную функцию.Чтобы просто получить что-то , вы можете передать их через MAX:

SELECT
    MAX(id_incident_project) AS ID,
    MAX(i.title) AS title,
    MAX(companyname) as social_name,
    username as tech_name,
    MAX(ia.DESCRIPTION_TEXT) as description,
    MAX(CONVERT(varchar, ia.ACTIONDATE, 101)) as action_date,
    MAX(CAST(TIME as INT)) as acting_time,
    MAX(CAST(actions_time as INT)) AS total_time
FROM
    incident i
    INNER JOIN incident_0001 i1 ON i1.ID_INCIDENT = i.ID_INCIDENT
    INNER JOIN incident_action ia ON ia.ID_INCIDENT = i.ID_INCIDENT
    INNER JOIN agent a ON a.ID_AGENT = ia.ID_AGENT
    INNER JOIN username u on u.ID_USERNAME = a.ID_USERNAME
WHERE
    ia.ACTIONDATE BETWEEN '## START DATE (YYYYMMDD)##' AND '## END DATE (YYYYMMDD)##'
GROUP BY username

Однако, когда есть несколько строк для одного и того же username после завершения всех объединений, этоподход будет рисковать значения из различных исходных строк, выводимых.Например, если имя пользователя «JohnSmith» имело (скажем) два инцидента, один на 2019-01-01 с названием «Zombie Sighting», а второй на 2019-03-31 с названием «Aitch Dropping», томаксимальный «извлеченный заголовок» будет «Прицел зомби» с «максимальной» датой, извлеченной из 2019-03-31, поэтому для различных инцидентов.

Чтобы избежать этого, вы можете заменить GROUP BY навместо этого разделите на username, упорядочите инциденты и выберите одно на username в последовательном порядке:

SELECT
    ID, title, social_name, tech_name, description,
    action_date, acting_time, total_time
FROM (
    SELECT
        id_incident_project) AS ID,
        i.title AS title,
        companyname as social_name,
        username as tech_name,
        ia.DESCRIPTION_TEXT) as description,
        CONVERT(varchar, ia.ACTIONDATE, 101) as action_date,
        CAST(TIME as INT) as acting_time,
        CAST(actions_time as INT) AS total_time,
        ROW_NUMBER () OVER (
            PARTITION BY username
            ORDER BY
                ia.ACTIONDATE DESC,   -- pick out latest
                i1.ID_INCIDENT DESC   -- tie breaker
        ) AS OrderNum
    FROM
        incident i
        INNER JOIN incident_0001 i1 ON i1.ID_INCIDENT = i.ID_INCIDENT
        INNER JOIN incident_action ia ON ia.ID_INCIDENT = i.ID_INCIDENT
        INNER JOIN agent a ON a.ID_AGENT = ia.ID_AGENT
        INNER JOIN username u on u.ID_USERNAME = a.ID_USERNAME
    WHERE
        ia.ACTIONDATE BETWEEN '## START DATE (YYYYMMDD)##' AND '## END DATE (YYYYMMDD)##'
) t
WHERE t.OrderNum = 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...