I have data like this:
ID | FTIME | STATUS
1 | 2020-02-27 08:11:12 | C-in
1 | 2020-02-27 08:11:15 | C-in
1 | 2020-02-27 08:11:18 | C-in
1 | 2020-02-27 17:11:01 | C-out
1 | 2020-02-27 17:11:03 | C-out
1 | 2020-02-27 17:11:08 | C-out
Assume the table name is TBL_RECORD
Now I need distinct to get data only with this case below:
2020-02-27 08:11:12
2020-02-27 17:11:08
So the result will be:
ID | FTIME | STATUS
1 | 2020-02-27 08:11:12 | C-in
1 | 2020-02-27 17:11:08 | C-out
I have tried my below code but it's not working.
SELECT DISTINCT ID, FTIME, STATUS FROM TBL_RECORD ORDER BY (CASE STATUS
WHEN 'C-in' THEN FTIME ASC
WHEN 'C-out' THEN FTIME DESC
END) DESC
Is there any way to get the lucky query?
I think, we have to restrict number of records in output so we have to use group by
instead of order by
. Please try below query -
SELECT
ID,
(CASE STATUS WHEN 'C-in' THEN MIN(FTIME) ELSE MAX(FTIME) END) AS FTIME,
STATUS
FROM TBL_RECORD
GROUP BY ID, STATUS;
I think you need below query ( Group by
data by Status
only)-
SELECT
(CASE STATUS WHEN 'C-in' THEN MIN(FTIME) ELSE MAX(FTIME) END) AS FTIME,
STATUS
FROM TBL_RECORD
GROUP BY STATUS;
If you need data only for ID = 1
then you have to add Where
clause in query like below -
SELECT
ID,
(CASE STATUS WHEN 'C-in' THEN MIN(FTIME) ELSE MAX(FTIME) END) AS FTIME,
STATUS
FROM TBL_RECORD
WHERE ID = 1
GROUP BY ID, STATUS;
You don't say which version of Oracle.
In Oracle 12.1 you can perform a union between two SELECT
s that limit to 1 row.
For example:
(
select *
from tbl_record
where status = 'C-in'
order by ftime
fetch next 1 rows only
)
union all (
select *
from tbl_record
where status = 'C-out'
order by ftime desc
fetch next 1 rows only
)
EDIT FOR ORACLE 10g :
In Oracle 10g you can do:
select *
from tbl_record
where status = 'C-in'
and ftime = (select min(ftime) from tbl_record where status = 'C-in')
or status = 'C-out'
and ftime = (select max(ftime) from tbl_record where status = 'C-out')
This one will work for multiple IDs.
If you're just using ID, FTIME and STATUS, GROUP
functions will work well. If you're pulling other columns please let me know and I'll show an alternative that's a bit more involved.
To get oldest by ID for C-in
:
SELECT ID, STATUS, MIN(FTIME) AS OUT_FTIME
FROM TBL_RECORD
WHERE STATUS = 'C-in'
GROUP BY ID, STATUS;
To get newest by ID for C-out
:
SELECT ID, STATUS, MAX(FTIME) AS OUT_FTIME
FROM TBL_RECORD
WHERE STATUS = 'C-out'
GROUP BY ID, STATUS;
To put it all together:
SELECT ID, STATUS, MIN(FTIME) AS OUT_FTIME
FROM TBL_RECORD
WHERE STATUS = 'C-in'
GROUP BY ID, STATUS
UNION SELECT ID, STATUS, MAX(FTIME) AS OUT_FTIME
FROM TBL_RECORD
WHERE STATUS = 'C-out'
GROUP BY ID, STATUS
ORDER BY ID, OUT_FTIME;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.