简体   繁体   English

对一对字段的SQL查询在一起

[英]SQL query on a pair of fields together

I have a table like this: 我有一张这样的桌子:

name | action      |    action_timestamp
------------------------------------------
ABC  | START_PLAY  |  2017-02-02 10:00:00
PQR  | START_PLAY  |  2017-02-02 11:00:00
ABC  | END_PLAY    |  2017-02-02 10:30:00
PQR  | END_PLAY    |  2017-02-02 11:05:00  

I want to get all the names who have started playing on or after a given timestamp and ended play on or before a given timestamp. 我想获得所有在给定时间戳上或之后开始播放并在给定时间戳上或之前结束播放的名称。

For example, if (action='START_PLAY' and action_timestamp >= 2017-02-02 10:00:00 ) and (action='END_PLAY' and action_timestamp <=2017-02-02 10:30:00) then the query should return me ABC 例如,如果(action ='START_PLAY'和action_timestamp> = 2017-02-02 10:00:00)和(action ='END_PLAY'和action_timestamp <= 2017-02-02 10:30:00),则查询应该还我ABC

I am not sure how should I make the conditions (viz. start_play and action_timestamp) as one. 我不确定如何使条件(即start_play和action_timestamp)合为一体。

Try this: 尝试这个:

SELECT *
FROM yourtable t1
WHERE EXISTS(
    SELECT 'STARTING'
    FROM yourtable t2
    WHERE t2.name = t1.name
    AND t2.action = 'START_PLAY'
    AND t2.timestamp >= '2017-02-02 10:30:00')
AND EXISTS (
    SELECT 'ENDING'
    FROM yourtable t3
    WHERE t3.name = t1.name
    AND t3.action = 'START_PLAY'
    AND t3.timestamp <= '2017-02-02 10:00:00')

Assuming that for each name exactly exists one row for START_PLAY and one row for END_PLAY , you can use something like the following: 假设每个name恰好存在一行START_PLAY和一行END_PLAY ,您可以使用类似以下内容:

select name, start_play, end_play
from (
        select name,
               max ( case when action = 'START_PLAY' then action_timestamp end) as start_play,
               max ( case when action = 'END_PLAY' then action_timestamp end) as end_play
        from yourTable 
        group by name
     )                 
where start_play > ...
  and end_play < ...     

The nested query performs a single scan of the table and creates one row for each name , with start_play and end_play on the row; 嵌套查询对表进行一次扫描,并为每个name创建一行,在该行上分别包含start_playend_play the outer part simply applies the filter on the rows resulting from the inner query. 外部仅将过滤器应用于内部查询产生的行。

Try this: 尝试这个:

select data.name from 
  (SELECT NAME,ACTION,ACTION_TIMESTAMP, ROW_NUMBER() OVER(PARTITION BY NAME ORDER BY ACTION) AS count FROM ST3 
  where (action='START_PLAY' AND ACTION_TIMESTAMP>='02-FEB-17 10.00.00')OR 
  (ACTION='END_PLAY' AND ACTION_TIMESTAMP<='02-FEB-17 10.30.00')) data
where data.count=2;

Use intersect like this: 像这样使用相交:

SELECT DISTINCT name FROM TBL WHERE action='START_PLAY' and action_timestamp >= '2017-02-02 10:00:00'
INTERSECT
SELECT DISTINCT name FROM TBL WHERE action='END_PLAY' and action_timestamp <= '2017-02-02 10:30:00'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM