Access SQL to return only first or last occurence by date

蹲街弑〆低调 提交于 2020-01-05 04:15:06

问题


First of all, I don't have many experiences with SQL and I have spent a lot of time trying to make it work. Please help.

I have original table from access database which contains columns: date, time, EP (point of entry), ID and rest of columns are just informational. No primary key, Change of table is last solution.

DateOS      TimeOS     EP    ID    Val1    Val2    Val3     Val4
1.2.2017    1:00:02    in    15    6280    blue    line1    s
1.2.2017    3:00:06    in    15    6280    blue    line1    s
1.2.2017    4:00:08    in    16    3147    red     line2    s
1.2.2017    5:00:10    out   20    6280    white   line3    c
1.2.2017    6:00:12    out   20    6280    white   line3    c
2.2.2017    2:00:04    in    16    3147    red     line2    s

I need to get only first (green in expected result)

DateOS      TimeOS     EP    ID    Val1    Val2    Val3     Val4
1.2.2017    1:00:02    in    15    6280    blue    line1    s
1.2.2017    4:00:08    in    16    3147    red     line2    s
1.2.2017    5:00:10    out   20    6280    white   line3    c

/ last (red in expected result) occurences that have unique combination of EP and ID.

DateOS      TimeOS     EP    ID    Val1    Val2    Val3     Val4
1.2.2017    3:00:06    in    15    6280    blue    line1    s
1.2.2017    6:00:12    out   20    6280    white   line3    c
2.2.2017    2:00:04    in    16    3147    red     line2    s

I got ideas from: Get the first instance of a row using MS Access

So far I have this (min function for first / max function for last):

SELECT
    FORMAT(pt.DateOS, 'dd.MM.yyyy') AS DateOS, 
    FORMAT(pt.TimeOS, 'HH:mm:ss') AS TimeOS, 
    pt.EP, pt.ID, pt.Val1, pt.Val2, pt.Val3, pt.val4
FROM [test07_dupl2] AS pt 
WHERE TimeOS 
IN
(
SELECT
    MIN(TimeOS) AS MinDateTimeOS 
FROM [test07_dupl2]
GROUP BY EP+ID
)

And this is result. It is considering just TimeOS. Second line does not belong there, because it is later date.

DateOS      TimeOS     EP    ID    Val1    Val2    Val3     Val4
1.2.2017    1:00:02    in    15    6280    blue    line1    s
2.2.2017    2:00:04    in    16    3147    red     line2    s
1.2.2017    5:00:10    out   20    6280    white   line3    c

The problem is that I need to consider DateOS + TimeOS. So I tried to write MIN(DateOS + TimeOS) and also create new column with value DateOS + TimeOS but both returned empty table. I'm not sure if I made some mistakes, or this is wrong approach.


回答1:


One method for handling this is to check that no records exist before the given record. This uses NOT EXISTS.

The logic is a bit complicated because the date/time is in two different columns. But for the first record:

SELECT pt.*
FROM [test07_dupl2] AS pt 
WHERE NOT EXISTS (SELECT 1
                  FROM [test07_dupl2] AS pt2
                  WHERE pt2.EP = pt.EP AND pt2.ID = pt.ID AND
                        (pt2.DateOS < pt.DateOS OR
                         pt2.DateOS = pt.DateOS AND pt2.TimeOS < pt.TimeOS
                        )
                 );

For the last, the final condition would be:

                        (pt2.DateOS > pt.DateOS OR
                         pt2.DateOS = pt.DateOS AND pt2.TimeOS > pt.TimeOS
                        )



回答2:


I have added DISTICT function to code from @Gordon Linoff to make sure that also duplicate lines with same date and time are gone.

SELECT DISTINCT t.*
FROM[SIMASSIST].[dbo].[TestDupl] AS t
WHERE
NOT EXISTS
(
    SELECT 1
    FROM[SIMASSIST].[dbo].[TestDupl] AS t2
    WHERE t2.EP = t.EP AND t2.ID = t.ID AND
    (
        (t2.DateOS < t.DateOS OR t2.DateOS = t.DateOS) AND 
        (t2.TimeOS < t.TimeOS)
    )
)


来源:https://stackoverflow.com/questions/52496411/access-sql-to-return-only-first-or-last-occurence-by-date

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!