Trying to compare timestamp value data - postgresql

In my Postgresql database, I have a column:
date_emailed timestamp NULL
When I insert it into the table, I use the value 'now()' for date_emailed column. Here is the example data:
When I try to query the row highlighted with the value '2022-10-17 06:39:10.036' I only get the value if I use >= and not =. For example:
Using '>=':
select date_emailed
from passdown.category_account_entry
where
date_emailed is not null
and date_emailed >= '2022-10-17 06:39:10.036'::timestamp
order by date_emailed desc;
My results return multiple rows, which is correct when using '>=':
But when I try to just use '=' to get the exact row, I get zero results:
select date_emailed
from passdown.category_account_entry
where
date_emailed is not null
and date_emailed = '2022-10-17 06:39:10.036'::timestamp
order by date_emailed desc;
So I thought I would convert it to an epoch test, and I noticed that the epoch value of date_emailed is different than the string value '2022-10-17 06:39:10.036'
select date_emailed,
date_part('epoch', date_emailed) as epoch_from_date_emailed,
date_part('epoch', '2022-10-17 06:39:10.036'::timestamp) as from_value
from passdown.category_account_entry
where
date_emailed is not null
and date_emailed >= '2022-10-17 06:39:10.036'::timestamp
order by date_emailed desc;
So what is different from the string value '2022-10-17 06:39:10.036' to the data in date_emailed? Am I missing something? Any tips or advise would be greatly appreciated.

As you can see in your sample data, it's a matter of precision, so using date_trunc function it could be solved
select date_trunc('milliseconds', date_emailed)
= '2022-10-17 06:39:10.036'::timestamp
from passdown.category_account_entry;
so now this sentence is true.

Related

How to store a temporary value in a Postgresql query and then use it multiple times?

I have this simple query:
SELECT COUNT(*)
FROM CompressorAlerts
WHERE CAST('2020-09-20' as timestamp) IS NULL OR faultTimestamp >= CAST('2020-09-20' as timestamp)
(I hardcoded 2020-09-20 ... it is really a value I am getting from somewhere else, irrelevant to this question, but I hardcoded it for simplicity).
As you can see, I am repeating twice CAST('2020-09-20' as timestamp). I want to avoid that, so I tried doing this:
WITH myDate as (SELECT CAST('2020-09-20' as timestamp))
SELECT COUNT(*)
FROM CompressorAlerts
WHERE myDate IS NULL OR faultTimestamp >= myDate
However, I get this error: column "mydate" does not exist.
How can I reference the myDate value I defined in the WITH clause? Am I doing something wrong?
mydate is the name of the CTE, not the name of the column expression inside it. Additionally you need to include the CTE in the FROM part of the query.
WITH params (mydate) as (
values (timestamp '2020-09-20')
)
SELECT COUNT(*)
FROM CompressorAlerts, params
WHERE mydate IS NULL
OR faultTimestamp >= mydate

SQL Server and index and null parameters

I have the below stored procedure that run against 2,304,697 records :
#startdate DATETIME NULL,
#enddate DATETIME NULL,
#drilldown VARCHAR(20) NULL
AS
BEGIN
SELECT
DATENAME(YEAR, ReceivingTime) as Year,
MAX(DATENAME(MONTH, ReceivingTime)) AS Month,
ProductionLocation,
CAST(COUNT(*) * 100.0 / SUM(COUNT(*) * 100) OVER (PARTITION BY DATENAME(YEAR, ReceivingTime), MONTH(ReceivingTime)) AS DECIMAL(10,2)) AS TotalsByMonth,
CAST(COUNT(*) * 100.0 / SUM(COUNT(*) * 100) OVER (PARTITION BY DATENAME(YEAR, ReceivingTime)) AS DECIMAL(10, 2)) AS TotalsByYear
FROM
Jobs_analytics
WHERE
ProductionLocation IS NOT NULL
AND ((ReceivingTime BETWEEN dbo.cleanStartDate(#startdate) AND dbo.cleanEndDate(#enddate))
AND #startdate IS NULL)
OR ((YEAR(ReceivingTime) = #drilldown) AND #drilldown IS NULL)
GROUP BY
DATENAME(YEAR, ReceivingTime),
DATEPART(MONTH, ReceivingTime), ProductionLocation
ORDER BY
DATENAME(YEAR, ReceivingTime),
DATEPART(MONTH, ReceivingTime)
The query works well in that it returns a data set in about 8 seconds. But I like to get the speed better So I added the below index:
CREATE INDEX RecDateTime
ON Jobs_analytics(RecDateTime, ProductionLocation)
go
however that really didn't improve anything. So I ran the execution plan and I notice that the my index is being used and the cost was 35% and my sort was at 6%.
So I reworked my where clause from this:
WHERE ProductionLocation IS NOT NULL AND
((ReceivingTime BETWEEN dbo.cleanStartDate(#startdate) and dbo.cleanEndDate(#enddate) ) AND #drilldown IS NULL)
OR ((YEAR(ReceivingTime) = #drilldown) AND #startdate IS NULL)
to this:
WHERE ProductionLocation IS NOT NULL AND
ReceivingTime BETWEEN dbo.cleanStartDate('2018-07-01') and dbo.cleanEndDate('2019-08-25')
and I got the query to run in a second. As you can see there is no more filter and the cost on the cluster is at 3%..( something I did not realize)
The NULL parameter checks are for a report that sometimes will have null values set. so I don't have to maintain two stored procedures. I can write a second stored procedure and just remove the where clause items but I rather not. is there any index or changes to my query that anyone could suggest that might help
Thanks
Mike
Okay if anyone comes across this this is what I found out:
I was testing the wrong parameter for null values within the OR
clause.
I have function that adds the hh:mm:ss to a date that was also
causing me problem.
I fixed both those items and the query runs in about a second.

result to be displayed in single column

I am working on PostgreSQL, below is my query which returns min and max dates from the table based on the condition.
select min(created_date),
max(created_date)
from myTable
where mode='auto'
and status='released'
group by mode;
Result:
min max
date date
2012-01-15 2016-11-24
created_date is of type date.I want the result to be displayed in single column as below.
created_date
date
2012-01-15
2016-11-24
You should use a UNION or UNION ALL:
select min(created_date),
from myTable
where mode='auto'
and status='released'
group by mode
UNION ALL
select max(created_date)
from myTable
where mode='auto'
and status='released'
group by mode;

Filtering date does not return correct data

I have the following query.
SELECT *
FROM (SELECT temp.*, ROWNUM AS rn
FROM ( SELECT (id) M_ID,
CREATION_DATE,
RECIPIENT_STATUS,
PARENT_OR_CHILD,
CHILD_COUNT,
IS_PICKABLE,
IS_GOLDEN,
trxn_id,
id AS id,
MASTER_ID,
request_wf_state,
TITLE,
FIRST_NAME,
MIDDLE,
LAST_NAME,
FULL_NAME_LNF,
FULL_NAME_FNF,
NAME_OF_ORGANIZATION,
ADDRESS,
CITY,
STATE,
COUNTRY,
HCP_TYPE,
HCP_SUBTYPE,
is_edit_locked,
record_type rec_type,
DATA_SOURCE_NAME,
DEA_DATA,
NPI_DATA,
STATE_DATA,
RPPS,
SIREN_NUMBER,
FINESS,
ROW_NUMBER ()
OVER (PARTITION BY id ORDER BY full_name_fnf)
AS rp
FROM V_RECIPIENT_TRANS_SCRN_OP
WHERE 1 = 1
AND creation_date >=
to_date( '01-Sep-2015', 'DD-MON-YYYY') AND creation_date <=
to_date( '09-Sep-2015', 'DD-MON-YYYY')
ORDER BY CREATION_DATE DESC) temp
WHERE rp = 1)
WHERE rn > 0 AND rn < 10;
Issue is, that the above query does return data which has creation_date as '09-Sep-2015'.
NLS_DATE_FORMAT of my database is 'DD-MON-RR'.
Datatype of the column creation_date is date and the date format in which date is stored is MM/DD/YYYY.
Since your column creation_date has values with non-zero time components, and the result of to_date( '09-Sep-2015', 'DD-MON-YYYY') has a zero time component, the predicate creation_date <= to_date( '09-Sep-2015', 'DD-MON-YYYY') is unlikely to match. As an example, "9/9/2015 1:07:45 AM" is clearly greater than "9/9/2015 0:00:00 AM", which is returned by your to_date() call.
You will need to take into account the time component of the Oracle DATE data type.
One option is to use the trunc() function, as you did, to remove the time component from values of creation_date. However, this may prevent the use of index on creation_date if it exists.
A better alternative, in my view, would be to reformulate your predicate as creation_date < to_date( '10-Sep-2015', 'DD-MON-YYYY'), which would match any time values on the date of 09-Sep-2015.

Get min date in Postgres

How do I get the min date of a timestamp field?
I tried to use
select min(myDatefield) from mytable
but this code doesn't returns the minimum date, but all dates.
Any clue why?
Try this, this might work for you.
SELECT *
FROM
(SELECT MCSSP_AUDIT_ACTIVITY_DATE
FROM MCSSP_MESG_AUDIT_BK
ORDER BY MCSSP_AUDIT_ACTIVITY_DATE ASC
)
WHERE rownum = 1;