Oracle SQL: ошибка с синтаксисом CTE и row_number () - PullRequest
0 голосов
/ 14 мая 2019

Обращаясь к @ scaisEdge

Я попробовал ваш запрос и получил сообщение об ошибке :

enter image description here

Мой оригиналзапрос дает плохой результат

enter image description here

Но вот результат, который мне нужен

enter image description here


Сводка: CTE и row_number () выдают ошибку ORA-00933: SQL command not properly ended


Фактический вопрос:

У меня есть запрос, который возвращает это

enter image description here

Но я хочу, чтобы он возвращал запрос, который удаляет дубликаты, то есть Date, Login ID и Subject должно быть Уникально .

Однако ID number должно быть минимум , а Creation Date должно быть самый ранний час дня

Вот желаемый вывод - обратите внимание, что последняя запись имела идентичный Creation Date, но при этом запись выбора выхода имела наименьшее значение ID number, то есть 542

enter image description here

Вот мой текущий запрос

SELECT TO_CHAR(MIN(I.INCIDENTID))                  AS "Incident ID",
          MIN(I.CREATIONDATE)                      AS "Creation Date",
          TO_CHAR(I.CREATIONDATE,'MM-DD-YYYY')     AS "Date",
          TRIM(MO.DOMAINUSERNAME)                  AS "Login ID",  
          TRIM(M.MESSAGESUBJECT)                   AS "Email Subject"
   FROM  INCIDENT I 
   JOIN  MESSAGE M
   ON M.MESSAGEID = I.MESSAGEID
   JOIN   MESSAGEORIGINATOR MO
   ON     M.MESSAGEORIGINATORID = MO.MESSAGEORIGINATORID           
   GROUP BY TO_CHAR(I.CREATIONDATE,'MM-DD-YYYY'),
            TRIM(MO.DOMAINUSERNAME),
            TRIM(M.MESSAGESUBJECT)

Мне посоветовали использовать CTE и row_number() дляустранить повторяющиеся даты, т.е. вернуть длинную дату с самым ранним временем в дне, но я получаю ошибку при следующем запросе (ORA-00933: SQL command not properly ended), поэтому, пожалуйста, помогите

with CTE as
(
SELECT t1.*,
       row_number() over (PARTITION BY I.CREATIONDATE ORDER BY I.CREATIONDATE) rn
FROM Mytable t1
)
SELECT *
FROM CTE
WHERE rn=1



SELECT TO_CHAR(MIN(I.INCIDENTID))                  AS "Incident ID",
          MIN(I.CREATIONDATE)                      AS "Creation Date",
          TO_CHAR(I.CREATIONDATE,'MM-DD-YYYY')     AS "Date",
          TRIM(MO.DOMAINUSERNAME)                  AS "Login ID", 
          TRIM(M.MESSAGESUBJECT)                   AS "Email Subject"
FROM  INCIDENT I 
   JOIN  MESSAGE M
   ON M.MESSAGEID = I.MESSAGEID
   JOIN   MESSAGEORIGINATOR MO
   ON     M.MESSAGEORIGINATORID = MO.MESSAGEORIGINATORID           
   GROUP BY TO_CHAR(I.CREATIONDATE,'MM-DD-YYYY'),
            TRIM(MO.DOMAINUSERNAME),
            TRIM(M.MESSAGESUBJECT)

Ответы [ 2 ]

1 голос
/ 14 мая 2019

Мне трудно понять эту часть:

SELECT t1.*, 
       row_number() over (partition by MIN(I.CREATIONDATE) order by TO_CHAR(I.CREATIONDATE,'MM-DD-YYYY')) rn
FROM Mytable t1

Partition by MIN(I.CREATIONDATE) не имеет смысла для меня.Не могли бы вы объяснить, что вы действительно хотите с этим запросом?

Разделение по разделам предназначено для предоставления измерения / с для ранжирования, которое вы собираетесь создать с помощью row_num.Если это разрешено базой данных (в чем я сомневаюсь), я даже не могу представить вывод.

EDITED

Используя функцию row_num, ваш запрос должен выглядеть следующим образом (изменить@fields к вашим полям реального имени).Там вы создаете «блоки разбиения» для каждого идентификатора входа в систему, а затем упорядочиваете строки, используя поля CREATIONDATE и ID, поэтому для каждой группы запись с меньшей комбинацией CREATIONDATE и меньшим идентификатором получит ранг 1 вrow_num

select
  q.@your_id_field, q.CREATIONDATE, q.@your_date_field, q.@your_login_id_field, q.@your_subject_field
from (
  select @your_id_field, CREATIONDATE, @your_date_field, @your_login_id_field, @your_subject_field,
    row_num() over (
      partition by @your_login_id_field, @your_subject_field
      order by I.CREATIONDATE asc, @your_id_field asc
    ) as rn
  -- I don't know your data, but your from maybe
  -- should look like this
  FROM INCIDENT I 
    JOIN MESSAGE M
      ON M.MESSAGEID = I.MESSAGEID
    JOIN MESSAGEORIGINATOR MO
      ON M.MESSAGEORIGINATORID = MO.MESSAGEORIGINATORID    
  ) q
where rn=1
1 голос
/ 14 мая 2019

Вы должны использовать группирование только по TRIM (MO.DOMAINUSERNAME), TRIM (M.MESSAGESUBJECT)

SELECT TO_CHAR(MIN(I.INCIDENTID))                  AS "Incident ID",
          MIN(I.CREATIONDATE)                      AS "Creation Date",

          TRIM(MO.DOMAINUSERNAME)                  AS Login_id,  
          TRIM(M.MESSAGESUBJECT)                   AS "Email Subject"
   FROM  INCIDENT I 
   JOIN  MESSAGE M
   ON M.MESSAGEID = I.MESSAGEID
   JOIN   MESSAGEORIGINATOR MO
   ON     M.MESSAGEORIGINATORID = MO.MESSAGEORIGINATORID           
   GROUP BY  TRIM(MO.DOMAINUSERNAME),
            TRIM(M.MESSAGESUBJECT)

Глядя на ваш пример, вы можете использовать внутреннее объединение в группе min_date с помощью login_id для получения всех связанных строк

select t1.* from  (
  SELECT TO_CHAR(MIN(I.INCIDENTID))                  AS "Incident ID",
          MIN(I.CREATIONDATE)                      AS "Creation Date",
          TO_CHAR(I.CREATIONDATE,'MM-DD-YYYY')     AS login_id,  
          TRIM(M.MESSAGESUBJECT)                   AS "Email Subject"
   FROM  INCIDENT I 
   JOIN  MESSAGE M
   ON M.MESSAGEID = I.MESSAGEID
   JOIN   MESSAGEORIGINATOR MO
   ON     M.MESSAGEORIGINATORID = MO.MESSAGEORIGINATORID           
   GROUP BY TO_CHAR(I.CREATIONDATE,'MM-DD-YYYY'),
            TRIM(MO.DOMAINUSERNAME),
            TRIM(M.MESSAGESUBJECT)

) t1 
INNER JOIN (
   SELECT  MIN(I.CREATIONDATE)  min_date, TO_CHAR(I.CREATIONDATE,'MM-DD-YYYY') login_id  
   FROM  INCIDENT I 
   JOIN  MESSAGE M
   ON M.MESSAGEID = I.MESSAGEID
   JOIN   MESSAGEORIGINATOR MO
   ON     M.MESSAGEORIGINATORID = MO.MESSAGEORIGINATORID           
   GROUP BY  login_id 
) t2  on t1."Creation Date" = t2.min_date and t2.login_id  = t1.login_id
...