Oracle SQL:CTE和row_number()语法错误

时间:2019-05-14 18:19:14

标签: sql oracle duplicates common-table-expression row-number

寻址@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

但是我希望它返回删除重复项的查询,即DateLogin IDSubject必须是唯一

然而,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)

建议我使用CTErow_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 个答案:

答案 0 :(得分:1)

您应仅使用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)

对于您的示例,您可以在login_id的min_date组上使用内部联接来获取相关行

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

答案 1 :(得分:1)

我很难理解这一部分:

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创建的排名提供尺寸。如果数据库允许(我对此表示怀疑),我什至无法想象输出。

已编辑

使用row_num函数,查询应如下所示(将@fields更改为实名字段)。 在该处,您为每个登录ID主题创建“分区块”,然后使用CREATIONDATE和ID字段对行进行排序,因此对于每个组,具有较少CREATIONDATE和较少ID组合的记录将按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