如何从访问表中获取选择性记录

Posted

技术标签:

【中文标题】如何从访问表中获取选择性记录【英文标题】:How can I get selective records from a table in access 【发布时间】:2017-08-16 11:21:27 【问题描述】:

以下是我的查询结果。但是有很多冗余记录,因此,我想过滤掉这个查询的结果。我的目标是每个角度只提取两条记录,第一条和最后一条。 例如当角度为195时, 我想在 date=2/27/2017, time=2:00:00 AM 和 日期为 2/27/2017 和 time=9:00:00 AM 时的第二条记录。 同样,当角度更改为 210 我想在 date=2/27/2017 time=10:00:00 AM 和另一条记录时获得它的第一条记录当日期和时间是 2/27/2017 和 9:00:00 PM。 对于所有记录也是如此。 我自己尝试过,但每个角度只返回一条记录,只返回顶部的一条,不知道如何获得最后一条。 我正在使用两个查询(Query1)

SELECT final.Date, final.Angle
FROM final
GROUP BY final.Date, final.Angle

第二个查询是 (fileredOUTput)

SELECT Query1.Date, Query1.Angle, (SELECT TOP 1 final.Date FROM final WHERE  Query1.Date=final.Date AND Query1.Angle= final.Angle)
 AS NewDate,
 (SELECT TOP 1 final.Angle FROM final WHERE  Query1.Date=final.Date AND Query1.Angle= final.Angle) AS NewAngle,
 (SELECT TOP 1 final.earthCol.Value FROM final WHERE  Query1.Date=final.Date AND Query1.Angle= final.Angle) AS NewE_CV, 
(SELECT TOP 1 final.earthCol.ColNu FROM final WHERE  Query1.Date=final.Date AND Query1.Angle= final.Angle) AS New_E_CN,
 (SELECT TOP 1 final.mars_Col.Value FROM final WHERE  Query1.Date=final.Date AND Query1.Angle= final.Angle) AS NewM_CV,
 (SELECT TOP 1 final.Col_apart FROM final WHERE  Query1.Date=final.Date AND Query1.Angle= final.Angle) AS New_CApart,
 (SELECT TOP 1 final.mars_Col.ColNu FROM final WHERE  Query1.Date=final.Date AND Query1.Angle= final.Angle) AS NewM_CN, 
(SELECT TOP 1 final.Time FROM final WHERE  Query1.Date=final.Date AND Query1.Angle= final.Angle) AS NewTime
FROM Query1, final
WHERE (((Query1.Date) Between [Forms]![Query Form]![txtStartDate] And [Forms]![Query Form]![txtEndDate]));

Query results and results I need are marked with red。 期待着听到您的意见。 谢谢。

【问题讨论】:

为什么在不涉及聚合函数的情况下使用 GROUP BY。您是否尝试执行 SELECT DISTINCT? 是的,我想选择不同的记录,但每个角度只能选择两个,不是全部 请看我发的图片 【参考方案1】:

试试这个

SELECT * FROM final INNER JOIN
(SELECT Min(DDate + DTime) AS DDateTime, Angle FROM final GROUP BY Angle
UNION SELECT Max(DDate + DTime) AS DDateTime, Angle FROM final GROUP BY Angle) mm
ON final.DDate + final.DTime = mm.DDateTime AND final.Angle = mm.Angle

请注意,在测试中我将前两列的名称分别更改为 DDate 和 DTime,因为 Date 和 Time 是保留字。

编辑

这使得它变得相当困难,尤其是在没有 LEAD/LAG 功能的 Access 中。以下应该可行,但有人可能有更优雅的解决方案!

SELECT final.* FROM final INNER JOIN
(SELECT MIN(DDateTime) AS MDateTime, Angle FROM
(SELECT (f.DDate+ f.DTime) AS DDateTime, f.Earth_Value, f.Mars_Value, f.Earth_Col, f.Mars_Col, f.Diff, f.Angle, f.Col_Apart,
IIF(ISNULL((SELECT MIN(m.DDate + m.DTime) FROM final m where f.angle <> m.angle and (f.DDate+f.DTime) < (m.DDate+m.DTime))),
(SELECT MAX(DDate+DTime) FROM final),(SELECT MIN(m.DDate + m.DTime) FROM final m where f.angle <> m.angle and (f.DDate+f.DTime) < (m.DDate+m.DTime))) AS NextChangeDateTime
FROM final f order by DDate, DTime) g
GROUP BY g.Angle,g.NextChangeDateTime
UNION
SELECT MAX(DDateTime) AS MDateTime, Angle FROM
(SELECT (f.DDate+ f.DTime) AS DDateTime, f.Earth_Value, f.Mars_Value, f.Earth_Col, f.Mars_Col, f.Diff, f.Angle, f.Col_Apart,
IIF(ISNULL((SELECT MIN(m.DDate + m.DTime) FROM final m where f.angle <> m.angle and (f.DDate+f.DTime) < (m.DDate+m.DTime))),
(SELECT MAX(DDate+DTime) FROM final),(SELECT MIN(m.DDate + m.DTime) FROM final m where f.angle <> m.angle and (f.DDate+f.DTime) < (m.DDate+m.DTime))) AS NextChangeDateTime
FROM final f order by DDate, DTime) g
GROUP BY g.Angle,g.NextChangeDateTime) FLDates
ON final.DDate + final.DTime = FLDates.MDateTime

编辑 2

从技术上讲,MS Access 中没有临时表之类的东西。实际上,您只需创建一个普通表并在每次要使用它时删除它的内容。

要创建表,您需要将其复制到查询窗口(SQL 视图)中,然后单击运行:

CREATE TABLE final (
    DDate       DATETIME     NOT NULL,
    DTime       DATETIME     NOT NULL,
    Earth_Value         DOUBLE   NOT NULL,
    Mars_Value         DOUBLE   NOT NULL,
    Earth_Col           INTEGER     NOT NULL,
    Mars_Col           INTEGER     NOT NULL,
    Diff           INTEGER     NOT NULL);

然后在您现有的查询类型之前(您只需要第一行):

INSERT into final
SELECT etc.

现在您将能够完全按原样运行我的查询。

【讨论】:

先生,它只为整个文件的每个角度提供了两条记录,但我的目标是在它们在一起时为每个角度提取两条记录。例如 (1 )90 (2)90 (3) 90 (4)10 (5)100 (6)90 (7)90 (8)90 现在我想得到 (1)(3)(4)(5 )(6) 和 (8) 条记录。每个角度有两个连续的记录。 查看我的编辑。我已更改为每批获得第一个和最后一个。 @Ayaz49 我没有收到回复。你现在修好了吗?如果是,请将其标记为已回答 先生,弹出一个错误,表示此表达式键入错误或太复杂而无法评估。我们可以把它分成两个查询,一个我们找到顶部值(底部值),另一个我们找到底部值(角度)。然后在第三个我们加入两个查询。? 谢谢您的回复先生。【参考方案2】:

可能是:

SELECT 
    * 
FROM 
    final,

    (SELECT 
        final.Date, Min(final.Time) As MinTime, Max(final.Time) As MaxTime, final.Angle
    FROM 
        final
    GROUP BY 
        final.Date, final.Angle) As T

WHERE
    final.Angle = T.Angle AND
    final.Date = T.Date AND
    ((final.Time = T.MinTime) OR (final.Time = T.MaxTime))
ORDER BY
    final.Date, final.Time, final.Angle

【讨论】:

不完全是我想要的。但是非常感谢,它真的很有帮助。 感谢您的帮助。【参考方案3】:

请记住,除非您还从表格中选择时间,否则您无法知道您正在检索哪些值。您所需输出中的日期和角度不是唯一的组合。

您可能需要对Access 语法稍作修改。

SELECT 
    final.Date AS dt, 
    MIN(final.Time) AS tm, 
    final.Angle AS ag
FROM 
    final 
GROUP BY 
    final.Date, final.Angle
UNION SELECT 
    final.Date, 
    MAX(final.Time), 
    final.Angle
FROM 
    final 
GROUP BY 
    final.Date, final.Angle
ORDER BY 
    dt, ag, tm;

编辑:SQL Fiddle 示例...http://sqlfiddle.com/#!9/2f638c/14

【讨论】:

感谢您的回答,虽然输出不是我想要的,但它确实很有帮助。它每个日期每个角度选择两条记录,但我只希望每个角度两条记录。谢谢。 只需做一点小改动:select min(final.Date) as dt, min(final.Time) as tm, final.Angle as ag from final group by final.Angle union select max(final.Date), max(final.Time), final.Angle from final group by final.Angle

以上是关于如何从访问表中获取选择性记录的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 SQL 选择的结果来获取另一个表中的记录?

如何从多个表中获取记录?

如何在 Asp.net MVC C# 中使用 Linq 从多个表中选择具有最大计数值的记录

如何从具有多个页面的表中获取表记录?

从一个表中选择 Laravel 5.1 中另一个表中不存在的所有记录

从具有三个外键的表中选择一个表[关闭]