【问题标题】:Access SQL to return only first or last occurence by date访问 SQL 以仅按日期返回第一次或最后一次出现
【发布时间】:2018-09-25 10:51:14
【问题描述】:

首先,我没有太多使用 SQL 的经验,而且我花了很多时间试图让它发挥作用。请帮忙。

我有来自 access 数据库的original table,其中包含以下列:datetimeEP(入口点)、ID,其余列仅供参考。 没有主键更改表是最后的解决方案。

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

我只需要firstexpected 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

/lastexpected result 中的红色)具有唯一 EP 和 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

我的想法来自: Get the first instance of a row using MS Access

到目前为止,我有这个(第一个最小函数/最后一个最大函数):

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
)

这是result。它只考虑 TimeOS。第二行不属于那里,因为它是较晚的日期。

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

问题是我需要考虑DateOS + TimeOS。因此,我尝试编写 MIN(DateOS + TimeOS) 并创建具有值 DateOS + TimeOS 的新列,但都返回了空表。我不确定我是否犯了一些错误,或者这是错误的方法。

【问题讨论】:

    标签: sql ms-access


    【解决方案1】:

    处理此问题的一种方法是检查在给定记录之前 是否存在任何记录。这使用NOT EXISTS

    逻辑有点复杂,因为日期/时间位于两个不同的列中。但对于第一条记录:

    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
                            )
                     );
    

    最后,最后的条件是:

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

    【讨论】:

    • 它运行良好!有趣的是,我花了 15 分钟才写完这篇文章,而且你眨眼就知道了。
    • @StanaMacala 。 . .它实际上并没有那么快;)与其他数据库相比,MS Access 的功能相当有限,所以我实际上不得不考虑这个。
    【解决方案2】:

    我在@Gordon Linoff 的代码中添加了DISTICT 函数 以确保具有相同日期和时间的重复行也消失了。

    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)
        )
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-07
      • 2017-09-14
      相关资源
      最近更新 更多