从Oracle SQL查询的输出中删除重复项

时间:2014-01-03 11:20:06

标签: sql oracle

我想从以下查询中删除重复的行。

     SELECT CONTACTS.ROWID as ROW_PASS,
            DUTY_ROTA.ROWID as ROW_PASS_ROTA,
            DUTY_ROTA.DUTY_DATE AS DUTY_DATE,
            DUTY_ROTA.DUTY_TYPE AS DUTY_TYPE,
            DUTY_ROTA.DUTY_OFFICER AS DUTY_OFFICER,
            DUTY_TYPES.DESCRIPTION AS DUTY_DESC,
            CONTACTS.SNAME AS FULLNAME,
            CONTACTS.MOBILE AS MOBILE_NO,
            CONTACTS.TELNO AS OFFICE_TEL 
         FROM DUTY_ROTA,
              DUTY_TYPES,
              CONTACTS 
         WHERE DUTY_DATE between SYSDATE-1 
               AND SYSDATE+18  
               AND DUTY_ROTA.DUTY_TYPE = DUTY_TYPES.DUTY_TYPE 
               AND duty_rota.DUTY_OFFICER = contacts.duty_id 
               AND SNAME IS NOT NULL 

我一直试图以下面的方式识别重复项 - (通过计数(*)和按列分组)

我也尝试了类似下面的代码片段,但没有帮助我得到正确的parenthisis缺失错误

SELECT CONTACTS.SNAME AS FULLNAME,
CONTACTS.ROWID as ROW_ID_CONTACT,
DUTY_ROTA.ROWID as ROW_ID_ROTA,
DUTY_ROTA.DUTY_TYPE AS DUTY_TYPE,
DUTY_ROTA.DUTY_OFFICER AS DUTY_OFFICER,
DUTY_TYPES.DESCRIPTION AS DUTY_DESC,
CONTACTS.MOBILE AS MOBILE_NO,
CONTACTS.OFFICETEL AS OFFICE_TEL, 
       Row_number() 
         OVER ( 
           partition BY CONTACTS.SNAME AS FULLNAME,
CONTACTS.ROWID as ROW_ID_CONTACT,
DUTY_ROTA.ROWID as ROW_ID_ROTA,
DUTY_ROTA.DUTY_TYPE AS DUTY_TYPE,
DUTY_ROTA.DUTY_OFFICER AS DUTY_OFFICER,
DUTY_TYPES.DESCRIPTION AS DUTY_DESC,
CONTACTS.MOBILE AS MOBILE_NO,
CONTACTS.OFFICETEL AS OFFICE_TEL
           ) AS rn 
FROM   DUTY_ROTA,DUTY_TYPES,CONTACTS WHERE DUTY_DATE between SYSDATE and SYSDATE+300 and contacts.duty_id = duty_rota.duty_officer 
AND DUTY_ROTA.DUTY_TYPE = DUTY_TYPES.DUTY_TYPE AND SNAME IS NOT NULL

4 个答案:

答案 0 :(得分:1)

使用如下所示的having子句,请删除rowid

SELECT count(*),DUTY_ROTA.DUTY_DATE AS DUTY_DATE,DUTY_ROTA.DUTY_TYPE AS DUTY_TYPE,DUTY_ROTA.DUTY_OFFICER AS DUTY_OFFICER,DUTY_TYPES.DESCRIPTION AS DUTY_DESC,CONTACTS.SNAME AS FULLNAME,CONTACTS.MOBILE AS MOBILE_NO,CONTACTS.TELNO AS OFFICE_TEL FROM DUTY_ROTA,DUTY_TYPES,CONTACTS WHERE DUTY_DATE between SYSDATE-1 and SYSDATE+18  AND DUTY_ROTA.DUTY_TYPE = DUTY_TYPES.DUTY_TYPE AND duty_rota.DUTY_OFFICER = contacts.duty_id and SNAME IS NOT NULL 
group by
 DUTY_ROTA.DUTY_DATE,
 DUTY_ROTA.DUTY_TYPE,
 DUTY_ROTA.DUTY_OFFICER,
 DUTY_TYPES.DESCRIPTION,
 CONTACTS.SNAME,
 CONTACTS.MOBILE,
 CONTACTS.TELNO
having count(*) > 1;

答案 1 :(得分:0)

据我记忆,在Oracle中,ROWID对于表中的每一行都是唯一的,因此您的查询将为where子句中的每一行返回一行。

答案 2 :(得分:0)

  

尝试使用RowNumber

SELECT * FROM
  (
  SELECT
  CONTACTS.SNAME AS FULLNAME,
  CONTACTS.ROWID as ROW_ID_CONTACT,
  DUTY_ROTA.ROWID as ROW_ID_ROTA,
  DUTY_ROTA.DUTY_TYPE AS DUTY_TYPE,
  DUTY_ROTA.DUTY_OFFICER AS DUTY_OFFICER,
  DUTY_TYPES.DESCRIPTION AS DUTY_DESC,
  CONTACTS.MOBILE AS MOBILE_NO,
  CONTACTS.OFFICETEL AS OFFICE_TEL, 
  Row_number() OVER ( Partition BY CONTACTS.SNAME AS FULLNAME,
                    CONTACTS.ROWID as ROW_ID_CONTACT,
                    DUTY_ROTA.ROWID as ROW_ID_ROTA,
                    DUTY_ROTA.DUTY_TYPE AS DUTY_TYPE,
                    DUTY_ROTA.DUTY_OFFICER AS DUTY_OFFICER,
                    DUTY_TYPES.DESCRIPTION AS DUTY_DESC,
                    CONTACTS.MOBILE AS MOBILE_NO,
                    CONTACTS.OFFICETEL AS OFFICE_TEL
                    Order By DUTY_ROTA.ROWID
                    ) AS RN
  FROM DUTY_ROTA,DUTY_TYPES,CONTACTS WHERE DUTY_DATE between SYSDATE and SYSDATE+300     
  AND contacts.duty_id = duty_rota.duty_officer     
  AND DUTY_ROTA.DUTY_TYPE = DUTY_TYPES.DUTY_TYPE AND SNAME IS NOT NULL
 )
Where RN=1

Refer

答案 3 :(得分:0)

 DELETE FROM table_name
 WHERE rowid NOT IN
                   ( 
                     SELECT MIN(rowid)
                     FROM table_name
                     GROUP BY column1, column2, column3...
                   ) ;

 CREATE TABLE t2 AS SELECT DISTINCT * FROM t1;