比较两个最新行,并根据location_id返回true或false

时间:2019-07-11 11:44:14

标签: sql oracle

我有表名Locations,它具有三个字段。我需要根据last_update_date查找特定人的id的最新两行,并比较这两最新行的location_id,如果两个location_id相同,则返回true,否则返回false。

我尝试使用join编写查询,但似乎无法解决我的问题。

表格摘要。 片段1:

Locations       
person_id   last_update_date              location_id
368         21/10/08 14:37                     234
368         28-02-00 06:18:12.000000000 AM     431
368         11-02-98 03:56:33.000000000 AM     431
368         13-01-98 08:50:37.000000000 AM     212

摘要2:

person_id   last_update_date              location_id
368         21/10/08 14:37                     null
368         28-02-00 06:18:12.000000000 AM     431
368         11-02-98 03:56:33.000000000 AM     431
368         13-01-98 08:50:37.000000000 AM     212

摘要3:

person_id   last_update_date              location_id
368         21/10/08 14:37                     431
368         28-02-00 06:18:12.000000000 AM     431
368         11-02-98 03:56:33.000000000 AM     431
368         13-01-98 08:50:37.000000000 AM     212

摘要4:

person_id   last_update_date              location_id
368         21/10/08 14:37                     431

对于上面的表snippet1,人员ID 368的两个最新行是前两行,它们没有相同的location_id,因此在这种情况下我想返回false。请帮我与oracle查询相同。 Snippet2,查询应返回false。 Snippet3,查询应返回true。 Snippet4,查询应返回false,因为没有其他行具有相同的person_id与之进行比较。

1 个答案:

答案 0 :(得分:1)

这是一个选择; test已有CTE,有用的代码从第7行开始。

SQL> with locations (person_id, last_update_date, location_id) as
  2    (select 368, to_date('21.10.2008 14:37', 'dd.mm.yyyy hh24:mi'), 234 from dual union all
  3     select 368, to_date('28.02.2000 06:18', 'dd.mm.yyyy hh24:mi'), 431 from dual union all
  4     select 368, to_date('11.02.1998 03:56', 'dd.mm.yyyy hh24:mi'), 431 from dual union all
  5     select 368, to_date('13.01.1998 08:50', 'dd.mm.yyyy hh24:mi'), 212 from dual
  6    ),
  7  temp as
  8    (select person_id, last_update_date, nvl(location_id, -1) location_id,
  9       row_number() over (partition by person_id order by last_update_date desc) rnd
 10     from locations
 11    )
 12  select person_id,
 13         min(last_update_date) min_date,
 14         max(last_update_date) max_date,
 15         case when min(location_id) <> max(location_id) or count(*) = 1 then 'false'
 16              else 'true'
 17         end flag
 18  from temp
 19  where rnd <= 2
 20  group by person_id;

 PERSON_ID MIN_DATE   MAX_DATE   FLAG
---------- ---------- ---------- -----
       368 28.02.2000 21.10.2008 false

SQL>

[编辑:如何使用CTE]

CTE(公用表表达式或带有分解子句的 )具有其语法。你不能发明自己的。

不喜欢您使用它:

(SELECT person_id,
        last_update_date,
        location_id,
        ROW_NUMBER ()
           OVER (PARTITION BY person_id ORDER BY last_update_date DESC)
           rnd
   FROM locations)
 as temp, select pid, ...

但是

WITH temp
     AS (SELECT person_id,
                last_update_date,
                location_id,
                ROW_NUMBER ()
                OVER (PARTITION BY person_id ORDER BY last_update_date DESC)
                   rnd
           FROM locations)
  SELECT pid, ...