将表复制到另一个表中,而不重复

时间:2019-04-30 07:56:49

标签: sql oracle

我写了一个bash脚本将一个表复制到另一个表中,然后它将删除原始表中的所有记录,但是我遇到了问题。

CREATE TABLE IF NOT EXISTS $TABLE AS SELECT DISTINCT * INTO $TABLE FROM T1 WHERE DTA_RIF < TRUNC (SYSDATE -30);
DELETE FROM T1 WHERE DTA_RIF < TRUNC (SYSDATE -30);

对于此查询,我有重复项,并且我不想插入相同的记录。我没有PK,因此无法加入。 我以为DISTINCT可以解决我的问题,但我做不到。

3 个答案:

答案 0 :(得分:1)

您可能会得到重复的记录,因为这些记录在所有列中均与其他记录不完全匹配,因此您可以通过使用一列作为区别的参考来解决此问题。

答案 1 :(得分:0)

如果不存在$ TABLE作为选择表,则创建表*从T1的DTA_RIF

通过此查询,您可以获取不同的值。

答案 2 :(得分:0)

好吧,Oracle。由于您使用的子句在那里不起作用,因此必须首先将其删除,然后再创建它。根据是否只想忽略表的存在,可以选择以下选项之一;示例基于Scott的示例架构,因为我没有您的表格。

拖放+创建

SQL> DROP TABLE dist_emp;
DROP TABLE dist_emp
           *
ERROR at line 1:
ORA-00942: table or view does not exist


SQL> CREATE TABLE dist_emp
  2  AS
  3     SELECT DISTINCT *
  4       FROM emp
  5      WHERE hiredate < TRUNC (SYSDATE - 30);

Table created.

SQL>

使用PL / SQL将其删除(如果存在的话)+创建

SQL> DECLARE
  2     l_table_name  VARCHAR2 (30);
  3  BEGIN
  4     SELECT table_name
  5       INTO l_table_name
  6       FROM user_tables
  7      WHERE table_name = 'DIST_EMP';
  8
  9     EXECUTE IMMEDIATE 'drop table dist_emp';
 10  EXCEPTION
 11     WHEN NO_DATA_FOUND
 12     THEN
 13        NULL;
 14  END;
 15  /

PL/SQL procedure successfully completed.

SQL> CREATE TABLE dist_emp
  2  AS
  3     SELECT DISTINCT *
  4       FROM emp
  5      WHERE hiredate < TRUNC (SYSDATE - 30);

Table created.

SQL>

创建一次+截断+插入

SQL> CREATE TABLE dist_emp
  2  AS
  3     SELECT *
  4       FROM emp
  5      WHERE 1 = 2;

Table created.

SQL> TRUNCATE TABLE dist_emp;

Table truncated.

SQL> INSERT INTO dist_emp
  2     SELECT DISTINCT *
  3       FROM emp
  4      WHERE hiredate < TRUNC (SYSDATE - 30);

14 rows created.

SQL> -- Next time: don't drop it, just truncate its contents
SQL> TRUNCATE TABLE dist_emp;

Table truncated.

SQL> INSERT INTO dist_emp
  2     SELECT DISTINCT *
  3       FROM emp
  4      WHERE hiredate < TRUNC (SYSDATE - 30);

14 rows created.

SQL>

另外:

  • 我建议您始终指定该操作涉及的所有列。不要使用*。对于测试和演示目的,这很方便,但是对于生产而言,请全部命名,例如

    insert into dist_emp (deptno, empno, ename, job, sal)
    select deptno, empno, ename, job, sal
    from emp
    where hiredate < trunc(sysdate - 30);
    
  • 从sysdate减去30看起来像上个月。如果是这样,那么它将不能在所有情况下的大约50%起作用(因为几个月往往有28 / 29、30或31天)。更安全的选项可能是ADD_MONTHS函数,例如

    where hiredate < trunc(add_months(sysdate, -1))