UtterAccess.com
X   Site Message
(Message will auto close in 2 seconds)

Welcome to UtterAccess! Please ( Login   or   Register )

Custom Search
4 Pages V  1 2 3 > »   (Go to first unread post)
   Reply to this topicStart new topic
> Query Of A Query - Is This Possible?, Access 97    
 
   
dw85745
post Aug 2 2019, 06:21 PM
Post#1



Posts: 103
Joined: 29-September 10
From: AZ


Since a query returns a recordset, is it possible to then do a query on that returned recordset ?
If so how?
Go to the top of the page
 
GroverParkGeorge
post Aug 2 2019, 06:56 PM
Post#2


UA Admin
Posts: 35,685
Joined: 20-June 02
From: Newcastle, WA


Are you thinking of something other than nesting the queries?

SELECT *
FROM Query1
WHERE Query1.PK = 1

--------------------
My Real Name Is George. Grover Park Consulting is where I do business.
How to Ask a Good Question
Beginning SQL Server
Go to the top of the page
 
dw85745
post Aug 2 2019, 07:20 PM
Post#3



Posts: 103
Joined: 29-September 10
From: AZ


GroverParkGeorge Thanks for responding.

QUOTE
Are you thinking of something other than nesting the queries?


YES. This is what I want to do -- if possible.

1) Do a SQL SELECT query with a BETWEEN clause (date type) to obtain a Recordset which is "subset" of the table.
2) Run one or more queries against this subset recordset.

If possible, MAY solve my problem here:
https://www.UtterAccess.com/forum/index.php...owtopic=2054607
This post has been edited by dw85745: Aug 2 2019, 07:22 PM
Go to the top of the page
 
RJD
post Aug 2 2019, 08:44 PM
Post#4


UtterAccess VIP
Posts: 10,028
Joined: 25-October 10
From: Gulf South USA


Hi: Yes, this is common practice, using a query within another query. This can be done using another query as the FROM recordset, as a subquery, or as a result of an In clause, or other ways. David offered an example in the other thread.

Perhaps you could "rough out" a query using a query that you think might meet your needs, post the SQL and someone here could understand better what you mean and help you with the approach.

Even better would be a db that contains example data, together with a picture of what the final result should be.

HTH
Joe

--------------------
"Each problem that I solved became a rule, which served afterwards to solve other problems."
"You just keep pushing. You just keep pushing. I made every mistake that could be made. But I just kept pushing."

Rene Descartes 1596-1650 (Mathematician and Philosopher)
Go to the top of the page
 
dw85745
post Aug 2 2019, 09:26 PM
Post#5



Posts: 103
Joined: 29-September 10
From: AZ


RJD: Thanks for responding

I had tried this subquery but Errors on the FROM clause:
CODE
SELECT FIRST(t.fldOpen), MAX(t.fldHigh), MIN(t.fldLow), LAST(t.fldClose)
From (SELECT fldHistDateTime, fldHistOpen AS fldOpen, fldHistHigh AS fldHigh, fldHistLow AS fldLow, fldHistClose AS fldClose
  From Sales1
  WHERE fldHistDateTime BETWEEN [pDateBeg] And [pDateEnd]
  GROUP BY fldHistDateTime ASC) As t;


I recognize FIRST and LAST need to be resolved with MIN and MAX - if possible - using PhilS suggestion in the other thread.
AS an alternative I thought I could create a Temporary Table in the DB of the BETWEEN records and then run a query or
several (if need to do MIN and MAX separately) against that Temporary Table but will be slow since I'm accessing a DB
instead of Memory. SO thought if I could run a query against a query (whose recordset is already in memory) it will
be much faster.

FWIW I used GROUP BY instead of ORDER BY in the subquery as it is my understanding subqueries cannot have ORDER BY in them.
This post has been edited by dw85745: Aug 2 2019, 09:35 PM
Go to the top of the page
 
dale.fye
post Aug 3 2019, 06:55 AM
Post#6



Posts: 160
Joined: 28-March 18
From: Virginia


Your problem is where you put the ") as T"

Instead of:
CODE
SELECT FIRST(t.fldOpen), MAX(t.fldHigh), MIN(t.fldLow), LAST(t.fldClose)
From (SELECT fldHistDateTime, fldHistOpen AS fldOpen, fldHistHigh AS fldHigh, fldHistLow AS fldLow, fldHistClose AS fldClose
  From Sales1
  WHERE fldHistDateTime BETWEEN [pDateBeg] And [pDateEnd]
  GROUP BY fldHistDateTime ASC) As t;

Use this:
CODE
SELECT t.fldHistDateTime, FIRST(t.fldOpen), MAX(t.fldHigh), MIN(t.fldLow), LAST(t.fldClose)
From (
    SELECT fldHistDateTime, fldHistOpen AS fldOpen, fldHistHigh AS fldHigh, fldHistLow AS fldLow, fldHistClose AS fldClose
    FROM Sales1
    WHERE fldHistDateTime BETWEEN [pDateBeg] And [pDateEnd]
) As t
GROUP BY t.fldHistDateTime ASC

Note: If you are going to group on the HistDateTime field, you should also put that into the outer SELECT statement
This post has been edited by dale.fye: Aug 3 2019, 06:55 AM

--------------------
Dale Fye
Microsoft Access MVP 2013-2016
Developing Solutions, LLC
Go to the top of the page
 
GroverParkGeorge
post Aug 3 2019, 07:36 AM
Post#7


UA Admin
Posts: 35,685
Joined: 20-June 02
From: Newcastle, WA


I have not heard that you can't use an ORDER BY clause in a subquery. Perhaps if you can post a reference to the source of that information, I can learn something (always a good thing). Often the context of such advice makes a difference, so I'd like to read it in context. Thanks.

You know already, I think, that First() and Last() are not reliable in most situations because they both depend on the ORDER BY clause applied to the recordset at any given time.

Min() and Max() are usually more reliable because they are not dependent on sort order determined by ORDER BY clause. That's not to say that First() and Last() don't have a place. I suppose they can. It is to say that most of the time, the safer alternative is Min() and Max().

--------------------
My Real Name Is George. Grover Park Consulting is where I do business.
How to Ask a Good Question
Beginning SQL Server
Go to the top of the page
 
RJD
post Aug 3 2019, 07:40 AM
Post#8


UtterAccess VIP
Posts: 10,028
Joined: 25-October 10
From: Gulf South USA


Hi: I don't think we are going to be able to sort this out for you without a db with a table and some example records, and a display of what you expect as the result from those records. Could you provide that? This would be, I think, essential in helping us help you.

Your comments about not using ORDER BY in a subquery are not correct, and when you added the GROUP BY you included ASC, which is not correct syntax, and you did not provide any Total selections for the fields in the subquery when you used GROUP BY. Thus the errors, our confusion and need for clarification.

HTH
Joe

--------------------
"Each problem that I solved became a rule, which served afterwards to solve other problems."
"You just keep pushing. You just keep pushing. I made every mistake that could be made. But I just kept pushing."

Rene Descartes 1596-1650 (Mathematician and Philosopher)
Go to the top of the page
 
dw85745
post Aug 3 2019, 08:56 AM
Post#9



Posts: 103
Joined: 29-September 10
From: AZ


Thanks all for responding.

Have a lot to go over today with your posts.
A quick comment:
-----------
dale.fry:
-----------
Noticed I had ASC as part of GROUP BY as you also did in your rework of my code.
That was my error as ASC is only used with ORDER BY.
Have not evaluated the rest.

RJD thanks for pointing this out.

-------------------
GroverParkGeorge
------------------------
See my last comments to your post in: https://www.UtterAccess.com/forum/index.php...owtopic=2054607

---------
RJD
--------
See what I can do. Never posted an image to the forum so will have to research how.
Here's it in hard form as an example (tried both code and quote and code gave best formatting).

CODE
The table would look like this
(primary key)
fldHistDateTime     fldHistOpen    fldHistHigh    fldHistLow    fldHistClose     '<< Field Order

7/26/2019 12:54:00 PM    3023.5    3024    3023.5    3023.75
7/26/2019 12:54:00 PM    3023.75    3023.75    3023.5    3023.5
7/26/2019 12:55:00 PM    3023.5    3023.75    3023.5    3023.75
7/26/2019 12:56:00 PM    3023.5    3024.5    3023.5    3024.5
7/26/2019 12:57:00 PM    3024.25    3024.5    3024    3024.5
7/26/2019 12:57:00 PM    3024.5    3024.75    3024.5    3024.5
7/26/2019 12:58:00 PM    3024.75    3024.75    3024.5    3024.75
7/26/2019 12:59:00 PM    3025    3025    3024.75    3024.75
7/26/2019 1:00:00 PM    3025    3025    3024.5    3024.75
7/26/2019 1:00:00 PM    3025    3025    3024.5    3024.5
No Gap - put here for easy of reading groups
7/30/2019 8:47:00 AM    3008.5    3009    3007.5    3007.75
7/30/2019 8:48:00 AM    3007.75    3008.5    3007.5    3008
7/30/2019 8:49:00 AM    3007.75    3009.75    3007.5    3009.25
7/30/2019 8:50:00 AM    3009.5    3010    3007.75    3008.5
7/30/2019 8:51:00 AM    3008.25    3009.25    3007.75    3009.25
7/30/2019 8:52:00 AM    3009    3010.5    3008.5    3010.5
7/30/2019 8:53:00 AM    3010.5    3010.5    3009.75    3010.25
7/30/2019 8:54:00 AM    3010.25    3010.5    3009.75    3010.5
7/30/2019 8:55:00 AM    3010.5    3010.75    3009.75    3010.75
7/30/2019 8:56:00 AM    3010.75    3011.25    3010.5    3011
7/30/2019 8:57:00 AM    3011    3011.75    3011    3011.5
7/30/2019 8:58:00 AM    3011.5    3011.75    3010.5    3011
7/30/2019 8:59:00 AM    3011    3011    3010.5    3010.5

-----------------
Result Set I am After
'Don't worry about the fldHistDateTime time stamp as using the Oldest Date in the BETWEEN clause
'to identify each Group of data
fldHistOpen = oldest date and record value for this field in the group
fldHistHigh = MAX value in the group
fldHistLow = MIN value in the group
fldHistClose = most current date and record value for this field in the group.
---------------------------
fldHistDateTime     fldHistOpen    fldHistHigh    fldHistLow    fldHistClose     '<< Query Output

7/26/2019 12:00:00 PM    3023.5    3025       3023.5         3024.5
7/30/2019 8:00:00 AM    3008.5    3011.75       3007.5         3010.5

This post has been edited by dw85745: Aug 3 2019, 09:08 AM
Go to the top of the page
 
dw85745
post Aug 3 2019, 09:24 AM
Post#10



Posts: 103
Joined: 29-September 10
From: AZ


-------------
RJD
----------
Here's a link to one of many talking about NOT using ORDER BY in a subquery.

https://www.w3resource.com/SQL/subqueries/u...-subqueries.php
For some reason link comes up NOT found, so here from my browser address line
QUOTE
www.w3resource.com/SQL/subqueries/understanding-SQL-subqueries.php


Even quote URL does not work to get you there.
From the page:
QUOTE
Subqueries cannot manipulate their results internally, therefore ORDER BY clause cannot be added into a subquery. You can use an ORDER BY clause in the main SELECT statement (outer query) which will be the last clause.




Another, but Kinda poor example debating the issue.
https://stackoverflow.com/questions/2101908...d-in-a-subquery
This post has been edited by dw85745: Aug 3 2019, 09:35 AM
Go to the top of the page
 
dw85745
post Aug 3 2019, 11:33 AM
Post#11



Posts: 103
Joined: 29-September 10
From: AZ


Trying to solve the query is my primary objective BUT out of that a number of questions have arisen
and the subject of this thread "Query of A Query".

In this regard I was NOT thinking of a subquery as part of the primary query.
BUT the bigger question of what is really going on behind the scenes and
whether I can use that information to do whatever.
My understanding -- if correct:

1) JET (or some other database) holds the data which resides on disk.
2) SQL is a language which allows one to interface and obtain data from the database.
3) Access - which is both a GUI and has some type of scripting/language capability -,
lets one view a database (in this case JET) and as part of that GUI
implementation allow one to execute SQL code.
4) No matter whether one executes SQL using Access, VB, or some other language or method
a result set is returned. My presumption is that this result set resides in memory and how that
result set is presented to the user is dependent on from where it was executed and the code instructions
on how one wishes to display/process that result set.
In Access's case, if one executes a Query within the Access Query Tab
the result set is presented in display form as a recordset.
5) If my presumption is correct, any SQL result set exists in memory.
6) The question then becomes one of whether that result set in memory from the first query can be used as data for use in a second or another query?
For example:
Database Recordset contains data from 1/1/2018 to 12/31/2018
First Query return data for period: 6/1/2018 to 6/30/2018
Second Query now would use the First Query return data recordset as input.
This post has been edited by dw85745: Aug 3 2019, 11:39 AM
Go to the top of the page
 
RJD
post Aug 3 2019, 12:02 PM
Post#12


UtterAccess VIP
Posts: 10,028
Joined: 25-October 10
From: Gulf South USA


Hmmm... Just to make sure where we are with this, I created a demo of two queries with subqueries. The table contains a field with C, B, F, A, G, D, E, one alpha character per record for 7 records. One subquery uses ASC sort, and the main query selects the resulting field (without a sort) - and the order is as done in the subquery, A-G. The other subquery uses DESC sort, and the main query selects the resulting field (again, without a sort) - and the order is reversed, as done in the subquery, G-A. Ordering is NOT done in the main query, but in the subquery alone.

To test this further, these two queries were copied and Top 2 added to the main query. In the ASC subquery query, this produces A, B. In the DESC subquery query, this produces G, F. Again, with no sorting in the main query.

So, in fact, the ORDER BY in the subquery does work, except perhaps in the case of First and Last used without grouping.

But the First and Last functions are of value, IMO, only in very specific circumstances.

I'll take a look at your posted data and desired results. It would have been much easier if you could have posted a db with the table, but I'll see what I can do. In any case, my first glance at the table seems to indicate the need for a value associated with the Min and Max time of the group rather than the First or Last of the values. But as I said, I'll see what I can do with this.

HTH
Joe
Attached File(s)
Attached File  SubqueryOrderBy.zip ( 18.94K )Number of downloads: 3
 

--------------------
"Each problem that I solved became a rule, which served afterwards to solve other problems."
"You just keep pushing. You just keep pushing. I made every mistake that could be made. But I just kept pushing."

Rene Descartes 1596-1650 (Mathematician and Philosopher)
Go to the top of the page
 
RJD
post Aug 3 2019, 01:30 PM
Post#13


UtterAccess VIP
Posts: 10,028
Joined: 25-October 10
From: Gulf South USA


Okay, here's what I found, and what I did.

You had multiple same dates and times. Without any other indications it is not possible to know which record comes first. This impacts the first two records in your post (among others). So, I added an Autonumber ID and entered the records in the same order you posted them. This ID is used later to differentiate the records and provide proper ordering for the first and last records of the date/hour group (NOT First and Last functions, which are not used at all in this solution - as inappropriate).

Your Hour groups include the next hour with 00 minutes. That is, 1:00 PM is included in the hour 12 group. This is achieved by subtracting 1 second from the fldHistDateTime, since you are not using seconds in your DateTime value.

To achieve the results you wanted ...

Extract the HistDate and HistHour values (adjusting the hour by -1 second) So that proper grouping can be achieved.
Sequence records within Date and Hour groups, by combining the datetime and ID.
Identify the first and last sequence numbers within the datehour groups. Name them "First" and "Last" - again, NOT the grouping functions. This uses a separate query identifying the min and max order numbers and then comparing these against the overall order to determine first and last.
Display the values in a Totals (Group By) query (grouping on Date and Hour), using "First" and "Last" text indicators within logic (see query). Then use the Min and Max for the other two values.

See the demo attached, using your posted table. See if it does what you want.

Look at the final results query, then you can track back to see how this is built up, as a query stack, with no subqueries (although these could be combined to use the subquery approach - I just thought it would be easier to follow separately) and no First or Last functions.

You (or others) may be able to simplify this process, but when I came to a solution that seemed to work, I stopped there.

HTH
Joe
Attached File(s)
Attached File  UA_20190803_dw85745.zip ( 21.15K )Number of downloads: 3
 

--------------------
"Each problem that I solved became a rule, which served afterwards to solve other problems."
"You just keep pushing. You just keep pushing. I made every mistake that could be made. But I just kept pushing."

Rene Descartes 1596-1650 (Mathematician and Philosopher)
Go to the top of the page
 
GroverParkGeorge
post Aug 3 2019, 01:34 PM
Post#14


UA Admin
Posts: 35,685
Joined: 20-June 02
From: Newcastle, WA


I see. Thanks for the references.

We're bumping into a semantic question here.

First, "can" in this context does not refer to the syntax itself. It is certainly possible to write SQL like this and get "a" result.

SQL
SELECT tblA.PK, tblA.*,
FROM tblA INNER JOIN (SELECT tblB .*
FROM tblB ORDER BY tblB.DateField) AS Subquery ON tblA.PK = Subquery.FK


The result may or may not be sorted in a meaningful way, though. And that's a different way of saying "You can't apply the ORDER BY in a subquery."

In other words, the question is not whether the rules permit it, but whether the results will be appropriate.

Second, there's a subtle difference between a definite article "the" and an indefinite article "a".

You CAN apply "a" Sort Order in a subquery, but it may or may not be effective as "the" Sort Order for the resulting recordset.

I know that's probably a bit pedantic. Still it's probably worth it to be sure we're all on the same page.

See Joe's specific comments in which he's explaining the practical impact of these considerations here.


--------------------
My Real Name Is George. Grover Park Consulting is where I do business.
How to Ask a Good Question
Beginning SQL Server
Go to the top of the page
 
dw85745
post Aug 3 2019, 02:06 PM
Post#15



Posts: 103
Joined: 29-September 10
From: AZ


Thanks to you both for your responses.

Need to take a break for a bit, so will digest last two comment, test RJD sample code and post back -- most likely tomorrow (Sunday) rather than today.
In regard to my post timed 12:33PM been thinking a bit about it -- will do more research later - but most likely when they designed SQL
(that raises another question as to whether SQL is a script language or not), they were concerned about the different OSes on which it would run,
and the fact those OSes needed to recapture memory at certain points; Hence since that memory might disappear -- unknown to SQL - the subquery
construct as part of the main query was designed to make sure that the memory allocated would still exist. I'm guessing the SQL designers
felt that one could dump the resulting recordset into an array or some other structure to take advantage of memory, if needed.
Go to the top of the page
 
RJD
post Aug 3 2019, 02:07 PM
Post#16


UtterAccess VIP
Posts: 10,028
Joined: 25-October 10
From: Gulf South USA


Hi again: I just looked back at the title line of this thread, and noticed that you indicated Access 97 as the version. Obviously, what I posted will not open in A97 as it was created in A2010. So, if it will help, here are the queries used in my last posted solution ...

qryDataPrep1

SELECT Sales1.ID, Sales1.fldHistDateTime, DateValue([fldHistDateTime]) AS HistDate, Hour(DateAdd("s",-1,[fldHistDateTime])) AS HistHour, CLng(DCount("*","[Sales1]","DateValue(fldHistDateTime)=#" & DateValue([fldHistDateTime]) & "# And Format([fldHistDateTime],'yyyymmddhhnn') & Format(ID,'000000')<='" & Format([fldHistDateTime],'yyyymmddhhnn') & Format([ID],'000000') & "'")) AS GroupOrder, Sales1.fldHistOpen, Sales1.fldHistHigh, Sales1.fldHistLow, Sales1.fldHistClose
FROM Sales1
ORDER BY Sales1.ID;

qryDataPrep2

SELECT qryDataPrep1.ID, qryDataPrep1.fldHistDateTime, qryDataPrep1.HistDate, qryDataPrep1.HistHour, qryDataPrep1.GroupOrder, IIf([GroupOrder]=[FirstOrder],"First",IIf([GroupOrder]=[LastOrder],"Last","")) AS OrderPosition, qryDataPrep1.fldHistOpen, qryDataPrep1.fldHistHigh, qryDataPrep1.fldHistLow, qryDataPrep1.fldHistClose
FROM qryDataPrep1 INNER JOIN qryGroupOrderRange ON qryDataPrep1.HistDate = qryGroupOrderRange.HistDate
ORDER BY qryDataPrep1.HistDate, qryDataPrep1.HistHour, qryDataPrep1.GroupOrder;

qryGroupOrderRange

SELECT qryDataPrep1.HistDate, Min(qryDataPrep1.GroupOrder) AS FirstOrder, Max(qryDataPrep1.GroupOrder) AS LastOrder
FROM qryDataPrep1
GROUP BY qryDataPrep1.HistDate;

qryFinalResults

SELECT qryDataPrep2.HistDate, qryDataPrep2.HistHour, Max(IIf([OrderPosition]="First",[fldHistOpen],Null)) AS HistOpen, Max(qryDataPrep2.fldHistHigh) AS HistHigh, Min(qryDataPrep2.fldHistLow) AS HistLow, Max(IIf([OrderPosition]="Last",[fldHistClose],Null)) AS HistClose
FROM qryDataPrep2
GROUP BY qryDataPrep2.HistDate, qryDataPrep2.HistHour;

All this against your posted table, named Sales1, but with ID added to provide initial sequence of records.

See if this will help you accommodate my solution in your version of Access.

If not, perhaps someone else has the software to convert my A2010 db back to A97 - and see if it works there. I'd have to dig out and test some old computers to see if I could do this - something I would not look forward to.

HTH
Joe

--------------------
"Each problem that I solved became a rule, which served afterwards to solve other problems."
"You just keep pushing. You just keep pushing. I made every mistake that could be made. But I just kept pushing."

Rene Descartes 1596-1650 (Mathematician and Philosopher)
Go to the top of the page
 
dw85745
post Aug 4 2019, 08:46 AM
Post#17



Posts: 103
Joined: 29-September 10
From: AZ


--------------------------------------------------------
RJD: Thanks for all your effort on my behalf.
RE: last post stamped 03:07 PM
---------------------------------------------------------

1) Per thread title, I see from your response one can do a Query of Query.
Good to know info as never seen that done and my searches yielded nothing.

2) Regarding the 4 SQL queries provided Will test in a bit, but looking at queries, seems like a lot of work to get such simple information.
Will try and time this once I get up and going and then compare to
PhilS's SQL suggestion.
I also would think doing a SELECT with a BETWEEN and ORDER BY clause with DAO GetRows, and then
evaluating the returned recordset (now in an array) would be a lot faster -- but you never know.

Will post back when done.

---------------------------
GroverParkGeorge
--------------------------
Comments noted.
This post has been edited by dw85745: Aug 4 2019, 08:56 AM
Go to the top of the page
 
cheekybuddha
post Aug 4 2019, 09:39 AM
Post#18


UtterAccess VIP
Posts: 11,487
Joined: 6-December 03
From: Telegraph Hill


In SQL Server:
CODE
SELECT
  t.Contact
FROM (
  SELECT
    c.Firstname + ' ' + c.Surname AS Contact
  FROM Contacts c
  ORDER BY c.Surname DESC
) t
;

returns:
CODE
SQL Error [1033] [S0001]: The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified.


Just FYI!

d

--------------------


Regards,

David Marten
Go to the top of the page
 
GroverParkGeorge
post Aug 4 2019, 10:11 AM
Post#19


UA Admin
Posts: 35,685
Joined: 20-June 02
From: Newcastle, WA


"... unless TOP, OFFSET or FOR XML is also specified."

So this SQL returns records just fine.

SQL
SELECT *
FROM access.tblMealItem MI
INNER JOIN (SELECT top 100 *
FROM ACCESS.tblFoodItem FI
ORDER BY fi.FoodItem)
AS FI ON MI.FoodItemID=FI.FoodItemID



And I've found that it's pointless anyway, as noted in the foregoing discussions regarding "a" sort order being applied in a subquery as opposed to the "the" desired sort order being applied in the outer query.

And don't forget Access SQL <> T-SQL.
This post has been edited by GroverParkGeorge: Aug 4 2019, 10:16 AM

--------------------
My Real Name Is George. Grover Park Consulting is where I do business.
How to Ask a Good Question
Beginning SQL Server
Go to the top of the page
 
cheekybuddha
post Aug 4 2019, 11:24 AM
Post#20


UtterAccess VIP
Posts: 11,487
Joined: 6-December 03
From: Telegraph Hill


You probably want TOP 100% with that! wink.gif

I was just trying to explain where the OP may have heard that you can't ORDER BY in a sub-query.

thumbup.gif

d

--------------------


Regards,

David Marten
Go to the top of the page
 
4 Pages V  1 2 3 > » 


Custom Search


RSSSearch   Top   Lo-Fi    21st September 2019 - 12:53 PM