Sql查询以查找某些列具有不同值的行

时间:2015-06-19 05:27:00

标签: sql oracle

我在表格中有以下数据

    Employee id       Status       email          partition 
            A          P           a@mail.com      1
            A          P           a@mail.com      2 

            D          T           d@mail.com      1
            D          T           d@mail.com      2

            G           P          g@mail.com      1
            G           T          g@mail.com      2

我们希望一个员工的所有三列对于分区1和2应该是相同的。如果有任何员工,其中三个列中的任何一个在分区1和2之间是不同的,那么应该返回这两个记录。

对于上述数据,查询应返回Employee G的两条记录。 有人可以帮忙查询一下吗?

6 个答案:

答案 0 :(得分:2)

此代码将返回所有行,其中employee(单个记录)没有partition = 2或者两行中的某些字段不同。

select t1.*, t2.* 
from tbl t1
    left join tbl t2 
    on t2.Employee_id = t1.Employee_id 
    AND t2.partition >  t1.partition
where t2.Employee_id is null
OR t1.Status != t2.Status 
or t1.email != t2.email

答案 1 :(得分:0)

这应该会给你预期的结果:

<!-- 
<bean id="rtSenderTaskExecutor"
    class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor">
    <property name="workManagerName">
        <value>${org.quartz.threadPool.jndi}</value>
    </property>
</bean> -->

<!-- Local Thread Pool -->    
<bean id="rtSenderTaskExecutor"
    class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    <property name="corePoolSize" value="${org.quartz.threadPool.corePoolSize}" />
    <property name="maxPoolSize" value="${org.quartz.threadPool.maxPoolSize}" />
    <property name="queueCapacity" value="${org.quartz.threadPool.queueCapacity}" />
    <property name="keepAliveSeconds" value="${org.quartz.threadPool.keepAliveSeconds}"></property>
</bean>

答案 2 :(得分:0)

您可以更改编写复杂查询的表格结构,

简单的解决方案是拥有2个表

  1. 以员工ID为主键的表员工(员工ID,状态,电子邮件)
  2. 表分区(EID外键,分区号)。
  3. 这将确保您拥有更好的设计和非冗余表格。

答案 3 :(得分:0)

您可以使用分析 LAG()功能。

<强>设置

CREATE TABLE t
  (
    Employee_id VARCHAR2(1),
    Status      VARCHAR2(1),
    email       VARCHAR2(10),
    partition   INT
  );
​
INSERT ALL 
    INTO t (Employee_id, Status, email, partition)
         VALUES ('A', 'P', 'a@mail.com', 1)
    INTO t (Employee_id, Status, email, partition)
         VALUES ('A', 'P', 'a@mail.com', 2)
    INTO t (Employee_id, Status, email, partition)
         VALUES ('D', 'T', 'd@mail.com', 1)
    INTO t (Employee_id, Status, email, partition)
         VALUES ('D', 'T', 'd@mail.com', 2)
    INTO t (Employee_id, Status, email, partition)
         VALUES ('G', 'P', 'g@mail.com', 1)
    INTO t (Employee_id, Status, email, partition)
         VALUES ('G', 'T', 'g@mail.com', 2)
SELECT * FROM dual;
COMMIT;

<强>查询

SQL> WITH t1 AS(
  2  SELECT t.*, LAG(status) OVER(PARTITION BY employee_id, email ORDER BY status) rn FROM t
  3  ),
  4  t2 AS(
  5  SELECT Employee_id, Status, email, PARTITION FROM t1
  6  WHERE
  7  status <> rn
  8  )
  9  SELECT t.Employee_id,
 10    t.Status,
 11    t.email,
 12    t.partition
 13  FROM t,
 14    t2
 15  WHERE t.Employee_id = t2.Employee_id
 16  ORDER BY t.partition;

EMPLOYEE_ID STATUS EMAIL       PARTITION
----------- ------ ---------- ----------
G           P      g@mail.com          1
G           T      g@mail.com          2

SQL>

答案 4 :(得分:0)

试试这个,

Select 
    t1.* 
from 
    table t1, table t2
where 
    t1.partition < t2.partition 
and t1.employee_id = t2.employee_id
and (t1.status != t2.status or t1.email !=t2.email)

Union all

Select 
    t2.* 
from 
    table t1, table t2
where 
    t1.partition < t2.partition 
and t1.employee_id = t2.employee_id
and (t1.status != t2.status or t1.email !=t2.email)

答案 5 :(得分:0)

这是非常普遍的,只打一次数据:

select employee_id, status, email, partition 
  from ( 
    select test.*, 
        count(1) over (partition by employee_id, status, email) cnt1,
        count(1) over (partition by employee_id) cnt2
      from test )
  where cnt1 <> cnt2

SQLFiddle

此查询还将处理情况,当一个人有3行或更多行时,并非所有匹配。 如果一名员工只有一行 - 并且您希望将其显示为异常 - 请在最后一行添加or cnt2 = 1