【问题标题】:Selecting Entry and exit record for each entry in a table为表中的每个条目选择条目和退出记录
【发布时间】:2017-09-22 19:13:19
【问题描述】:

以下是我的表格中的示例

F_ID     R_ID       DATE    Col_A   Col_B   Col_C
 12      158      20161008    01      99     99
 12      158      20161012    01      01     99
 12      158      20161019    01      02     10
 12      158      20161022    99      01     10
 12      160      20161006    01      99     01
 12      160      20161011    99      01     99
 12      160      20161017    99      01     10
 17      167      20161013    99      01     01
 17      167      20161016    99      02     99
 17      167      20161020    02      01     10
 17      174      20161010    99      01     01
 17      174      20161012    01      02     11
 17      174      20161017    99      99     10

我想选择这样我得到以下结果

F_ID   R_ID    DATE     Col_A   Col_B   Col_C
12     158    20161008    01      01     99     -  Entry record
12     158    20161022    99      01     10     -  Exit Record
12     160    20161006    01      99     01     -  Entry record
12     160    20161017    99      01     10     -  Exit Record
17     167    20161013    99      01     01     -  Entry record
17     167    20161020    02      01     10     -  Exit Record
17     174    20161010    99      01     01     -  Entry record
17     174    20161017    99      99     10     -  Exit Record

For each  F_ID, R_ID:
When Col_A or Col_B = '01' and Col_C <>'10' - **It is an entry record**
When Col_C = '10' - **It is an exit record**

这里的逻辑是

1. Select the earliest entry record 
   **and** 
2. Select the latest exit record for each F_ID, R_ID

我正在考虑使用下面的联合...

Select * from tbl1 T
where 
T.Col_C = '10' and 
T.DATE = (select max(T2.DATE) from tbl1 T2
                                 where
                                 T2.Col_C = '10' and
                                 T2.R_ID = T.R_ID
                                 T2.F_ID = T.F_ID
          ) 

union

Select * from tbl1 K
where
(K.Col_A = '01' or K.Col_B = '01') and 
K.Col_C <> '10' and
K.DATE = (select min(K2.DATE) from tbl1 K2 where 
                      (K2.Col_A = '01' or K2.Col_B = '01') and 
                       K2.Col_C <> '10' and
                       K2.R_ID = K.R_ID
                       K2.F_ID = K.F_ID
          )

但是像我在同一张表上使用自联接一样使用联合会返回给我一个垃圾数据。

【问题讨论】:

  • Col_A &lt;&gt; '01'Col_B &lt;&gt; '01'Col_C &lt;&gt; '10' 会发生什么?这既不是Entry,也不是Exit记录,这是什么?你就这样跳过记录?
  • “垃圾数据”到底是什么意思?在我看来,该查询看起来不错。 ORDER BY 子句当然会有所帮助。并且UNION 没有多大意义,因为您不必消除重复项;请改用UNION ALL
  • Col_A '01' and Col_B '01' and Col_C '10' -- 这个条件仍然可以算入记录

标签: sql oracle select join union


【解决方案1】:

如果我理解正确,你需要这个:

SELECT * FROM (
    SELECT T1.*,   ROW_NUMBER() OVER(PARTITION BY F_ID  ,   R_ID order by DATE)   rn, 'Entry record' as rec FROM (
        SELECT * FROM your_table WHERE (Col_A = '01' or Col_B = '01') and Col_C <> '10'
    ) T1
    union all
    SELECT T2.*,   ROW_NUMBER() OVER(PARTITION BY F_ID  ,   R_ID order by DATE DESC)   rn , 'Exit record' as rec FROM (
        SELECT * FROM your_table WHERE  Col_C = '10'
    ) T2
) t3
where rn = 1

编辑

更简化的版本(感谢@ThorstenKettner)

SELECT * FROM (
    SELECT your_table.*, ROW_NUMBER() OVER(PARTITION BY F_ID, R_ID order by DATE) as rn, 'Entry record' as rec FROM your_table WHERE (Col_A = '01' or Col_B = '01') and Col_C <> '10'
    union all
    SELECT your_table.*, ROW_NUMBER() OVER(PARTITION BY F_ID, R_ID order by DATE DESC) as rn, 'Exit record' as rec FROM your_table WHERE Col_C = '10'
) t3
where rn = 1
ORDER BY F_ID, R_ID, DATE

【讨论】:

  • 这可以通过同时调用ROW_NUMBERWHERE 来简化,而不是嵌套它。然后:ORDER BY 子句将按所需顺序获取数据。
  • @ThorstenKettner - WHERE 子句如何同时实现?我不明白。
  • SELECT T1.*, ROW_NUMBER() OVER(PARTITION BY F_ID, R_ID order by DATE) as rn, 'Entry record' as rec FROM your_table WHERE (Col_A = '01' or Col_B = '01') and Col_C &lt;&gt; '10'
  • @ThorstenKettner - 哦,谢谢,我明白你的意思,你是对的。
  • 谢谢@OtoShavadze 这让我更接近,但我的进出记录不等。对于一些 F_ID 和 R_ID,我只有进入但没有退出记录,反之亦然。如何过滤以仅获取具有有效进入和退出记录的记录?
猜你喜欢
  • 1970-01-01
  • 2013-04-15
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 2016-08-13
  • 1970-01-01
  • 2015-08-21
  • 1970-01-01
相关资源
最近更新 更多