How can I get selective records from a table in access

ε祈祈猫儿з 提交于 2019-12-12 17:30:33

问题


Given below are the results of my query. But there are many redundant records, therefore, I want to filter out the results of this query. My goal is to extract only two records per angle, first and the last. For example when the angle is 195, I want to get its first record when the date=2/27/2017, time=2:00:00 AM and the second record when the date is 2/27/2017 and time=9:00:00 AM. Similarly when the angle is changed to 210 I want to get its first record when the date=2/27/2017 time=10:00:00 AM and the other record when the date and time is 2/27/2017 and 9:00:00 PM. And similarly for all the records. I tried to do it myself but it only returns one record per angle only the top one, dont know how do I get the last one. I am doing it using two queries, (Query1)

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

and second query is (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. Looking forward to hear from you. Thank you.


回答1:


Try this

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

Please note that in testing I changed the name of the first two columns to DDate and DTime respectively, because Date and Time are reserved words.

EDIT

That makes it considerably harder, particularly in Access which has no LEAD/LAG functions. The following should work, but someone might have a more elegant solution!

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

EDIT 2

Technically there is no such thing as a temporary table in MS Access. Really you just create a normal table and delete its contents every time you want to use it.

To create the table you need copy this into a Query Window (SQL View), and then click Run:

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

Then before your existing Query type (you just need the first line):

INSERT into final
SELECT etc.

Now you will be able to run my query exactly as is.




回答2:


It could be:

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:


Keep in mind that unless you also select the time from your table, you have no way of knowing which values you are retrieving. The date and angle in your required output isn't a unique combination.

You may need to modify slightly for Access syntax.

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;

EDIT: SQL Fiddle example... http://sqlfiddle.com/#!9/2f638c/14



来源:https://stackoverflow.com/questions/45712200/how-can-i-get-selective-records-from-a-table-in-access

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