如何获取没有重复记录的列表?

时间:2013-03-13 15:50:39

标签: sql oracle plsql oracle10g oracle11g

我需要获取一个没有重复记录值的列表。请查看查询列表以获取详细信息。

从原始表中查询第一个列表,第二个列表是添加两个函数的中间结果,第三个列表是期望结果。

请帮助获得第三个列表结果,任何机构都可以提供帮助,将非常感谢。

顺便说一下,硬件需要在最终结果中保留plsh.plsh_id,因此不能在第二个列表中使用distinct。 current_smc_value和previous_smc_value需要继续保持。

原始数据如下:

select plsh.plsh_id,
       plsh.patr_id,
       plsh.smc         CURRENT_SMC,
       plsh.create_date CURRENT_SMC_DATE
  from pat_liver_smc_his plsh
 where plsh.patr_id = 34461
 order by plsh.plsh_id desc;

,结果是

    PLSH_ID PATR_ID CURRENT_SMC CURRENT_SMC_DATE
1   10020   34461       22      2/19/2013 1:23:58 PM
2   10019   34461       22      2/19/2013 1:22:57 PM
3   10018   34461       27      2/19/2013 1:22:42 PM
4   10017   34461       27      2/19/2013 1:22:42 PM
5   10016   34461       27      2/19/2013 1:22:32 PM
6   10015   34461       27      2/19/2013 1:22:32 PM
7   10014   34461       27      2/19/2013 1:22:20 PM
8   10013   34461       27      2/19/2013 1:22:20 PM
9   10012   34461       27      2/19/2013 1:22:09 PM
10  10011   34461       27      2/19/2013 1:21:50 PM
11  10010   34461       24      2/19/2013 1:21:36 PM
12  10009   34461       22      2/19/2013 1:21:06 PM
13  10008   34461               2/19/2013 1:21:06 PM

需求需要获取previous_smc,previous_smc_date和trunc date,因此我创建了以下查询语句和两个函数。

select plsh.plsh_id,
       plsh.patr_id,
       tttt_gen_pkg.get_previous_SMC(plsh.patr_id, plsh.plsh_id) PREVIOUS_SMC,
       trunc(tttt_gen_pkg.get_previous_SMC_Date(plsh.patr_id, plsh.plsh_id)) PREVIOUS_SMC_DATE,
       plsh.smc CURRENT_SMC,
       trunc(plsh.create_date) CURRENT_SMC_DATE
  from pat_liver_smc_his plsh
 where plsh.patr_id = 34461
 order by plsh.plsh_id desc;

function get_previous_SMC(p_patr_id varchar2, p_plsh_id varchar2)
  return number is
  cursor c_smc is
    select plsh.smc
      from pat_liver_smc_his plsh
     where plsh.patr_id = p_patr_id
       and plsh.plsh_id < p_plsh_id
     order by plsh.plsh_id desc;
  v_rst number;
begin
  open c_smc;
  fetch c_smc
    into v_rst;
  close c_smc;
  return v_rst;
end;

function get_previous_SMC_Date(p_patr_id varchar2, p_plsh_id varchar2)
  return date is
  cursor c_smc is
    select plsh.create_date
      from pat_liver_smc_his plsh
     where plsh.patr_id = p_patr_id
       and plsh.plsh_id < p_plsh_id
     order by plsh.plsh_id desc;
  v_rst date;
begin
  open c_smc;
  fetch c_smc
    into v_rst;
  close c_smc;
  return v_rst;
end;

,结果是

    PLSH_ID PATR_ID PREVIOUS_SMC    PREVIOUS_SMC_DATE   CURRENT_SMC     CURRENT_SMC_DATE
1   10020   34461       22          2/19/2013               22          2/19/2013
2   10019   34461       27          2/19/2013               22          2/19/2013
3   10018   34461       27          2/19/2013               27          2/19/2013
4   10017   34461       27          2/19/2013               27          2/19/2013
5   10016   34461       27          2/19/2013               27          2/19/2013
6   10015   34461       27          2/19/2013               27          2/19/2013
7   10014   34461       27          2/19/2013               27          2/19/2013
8   10013   34461       27          2/19/2013               27          2/19/2013
9   10012   34461       27          2/19/2013               27          2/19/2013
10  10011   34461       24          2/19/2013               27          2/19/2013
11  10010   34461       22          2/19/2013               24          2/19/2013
12  10009   34461                   2/19/2013               22          2/19/2013
13  10008   34461                                                       2/19/2013

预计最终结果如下:如何获得?最终结果中需要PLSH_ID,因此上述查询语句的区别不起作用。

    PLSH_ID PATR_ID PREVIOUS_SMC    PREVIOUS_SMC_DATE   CURRENT_SMC     CURRENT_SMC_DATE
1   10020   34461       22          2/19/2013               22          2/19/2013
2   10019   34461       27          2/19/2013               22          2/19/2013
3   10018   34461       27          2/19/2013               27          2/19/2013
10  10011   34461       24          2/19/2013               27          2/19/2013
11  10010   34461       22          2/19/2013               24          2/19/2013
12  10009   34461                   2/19/2013               22          2/19/2013
13  10008   34461                                                       2/19/2013

Hi Egor,

Thank you very much for your effort. After a little bit modify your code I got below result,
it seems current_smc and current_smc_date order is correct but the previous_smc and previous_smc_date still not correct,
the result is like below:

    PLSH_ID PATR_ID PREVIOUS_SMC    PREVIOUS_SMC_DATE   CURRENT_SMC     CURRENT_SMC_DATE
1   10020   34461                                       22              2/19/2013
2   10019   34461   22              2/19/2013           22              2/19/2013
3   10018   34461   22              2/19/2013           27              2/19/2013
4   10017   34461   27              2/19/2013           27              2/19/2013
5   10010   34461   27              2/19/2013           24              2/19/2013
6   10009   34461   24              2/19/2013           22              2/19/2013
7   10008   34461   22              2/19/2013                           2/19/2013

A little bit modify of your code is like below:

select plsh_id,
       patr_id,
       PREVIOUS_SMC,
       PREVIOUS_SMC_DATE,
       CURRENT_SMC,
       CURRENT_SMC_DATE
  from (select plsh_id,
               patr_id,
               CURRENT_SMC,
               CURRENT_SMC_DATE,
               PREVIOUS_SMC,
               PREVIOUS_SMC_DATE,
               case
                 when decode(CURRENT_SMC,
                             lag(CURRENT_SMC) over(partition by t1.patr_id
                                  order by t1.plsh_id desc),
                             1) = 1 and decode(CURRENT_SMC_DATE,
                                               lag(CURRENT_SMC_DATE)
                                               over(partition by t1.patr_id
                                                    order by t1.plsh_id desc),
                                               1) = 1 and
                      decode(PREVIOUS_SMC,
                             lag(PREVIOUS_SMC)
                             over(partition by t1.patr_id order by
                                  t1.plsh_id desc),
                             1) = 1 and
                      decode(CURRENT_SMC,
                             lag(CURRENT_SMC) over(partition by t1.patr_id
                                  order by t1.plsh_id desc),
                             1) = 1 then
                  1
               end as the_same
          from (select plsh.plsh_id,
                       plsh.patr_id,
                       trunc(plsh.smc) CURRENT_SMC,
                       trunc(plsh.create_date) CURRENT_SMC_DATE,
                       lead(trunc(plsh.smc)) over(partition by plsh.patr_id order by plsh.plsh_id) PREVIOUS_SMC,
                       lead(trunc(plsh.create_date)) over(partition by plsh.patr_id order by plsh.plsh_id) PREVIOUS_SMC_DATE
                  from pat_liver_smc_his plsh
                 where plsh.patr_id = 34461) t1)
 where the_same is null
 order by patr_id, plsh_id desc;

Can you please help me to correct it? Some of you code I don't understand because you are more senior level than me. Thanks again!!!

最终的完美作品来自DazzaL。修改后的工作代码如下:

select plsh_id,
       patr_id,
       previous_smc,
       previous_smc_date,
       current_smc,
       current_smc_date
  from (select plsh_id,
               patr_id,
               previous_smc,
               previous_smc_date,
               current_smc,
               current_smc_date,
               row_number() over(partition by patr_id, current_smc, previous_smc order by plsh_id desc) rn
          from (select plsh_id,
                       patr_id,
                       plsh.smc current_smc,
                       plsh.create_date current_smc_date,
                       lag(plsh.smc) over(partition by patr_id order by plsh_id) previous_smc,
                       lag(plsh.create_date) over(partition by patr_id order by plsh_id) previous_smc_date
                  from pat_liver_smc_his plsh))
 where rn = 1 and patr_id = 34461
 order by patr_id, plsh_id desc

2 个答案:

答案 0 :(得分:1)

select plsh_id,
       patr_id,
       CURRENT_SMC,
       CURRENT_SMC_DATE,
       PREVIOUS_SMC,
       PREVIOUS_SMC_DATE
from (
    select plsh_id,
           patr_id,
           CURRENT_SMC,
           CURRENT_SMC_DATE,
           PREVIOUS_SMC,
           PREVIOUS_SMC_DATE,
           case when 
             decode(CURRENT_SMC, lag(CURRENT_SMC) over (partition by plsh.patr_id order by plsh.plsh_id desc), 1) = 1
             and   
             decode(CURRENT_SMC_DATE, lag(CURRENT_SMC_DATE) over (partition by plsh.patr_id order by plsh.plsh_id desc), 1) = 1
             and   
             decode(PREVIOUS_SMC, lag(PREVIOUS_SMC) over (partition by plsh.patr_id order by plsh.plsh_id desc), 1) = 1
             and   
             decode(CURRENT_SMC, lag(CURRENT_SMC) over (partition by plsh.patr_id order by plsh.plsh_id desc), 1) = 1
             then 1
           end as the_same
    from (
      select 
           plsh.plsh_id,
           plsh.patr_id,
           trunc(plsh.smc)         CURRENT_SMC,
           trunc(plsh.create_date) CURRENT_SMC_DATE,
           lead(trunc(plsh.smc)) over (partition by plsh.patr_id order by plsh.plsh_id) PREVIOUS_SMC,
           lead(trunc(plsh.create_date)) over (partition by plsh.patr_id order by plsh.plsh_id) PREVIOUS_SMC_DATE
      from pat_liver_smc_his plsh
      where plsh.patr_id = 34461
    )
)
where the_same is null
order by plsh.patr_id, plsh.plsh_id desc;

答案 1 :(得分:1)

等等;

select plsh_id, patr_id, previous_smc, previous_smc_date, 
       current_smc, current_smc_date
  from (select plsh_id, patr_id, previous_smc, 
               previous_smc_date, current_smc,
               current_smc_date,
               row_number() over(partition by patr_id, current_smc, 
                                 current_smc_date, previous_smc, 
                                 previous_smc_date  
                                 order by plsh_id desc) rn          
          from (select plsh_id, patr_id, current_smc,
                       trunc(current_smc_date) current_smc_date,
                       lag(current_smc) over(partition by patr_id 
                                             order by plsh_id) previous_smc,
                       trunc(lag(current_smc_date)
                               over(partition by patr_id
                                    order by plsh_id)) previous_smc_date
                  from pat_liver_smc_his))
 where rn = 1
 order by patr_id, plsh_id desc