Snowflake SQL: Get Last Day of Month Records - date

Where one would normally use EOMonth, in Snowflake there is no such function. They have LAST_DAY, but so far I have not been able to get that one to work neither. Does anyone see what I have done incorrectly below OR have a workaround to EOMonth in Snowflake?
My attempts:
SELECT *
FROM "NORCO"."UNITS_SNAPSHOT" AS US1
WHERE US1.CCODE LIKE '%514-L%' AND
US1.TIMESTAMP=(SELECT LAST_DAY(US1.TIMESTAMP,'MONTH')
FROM "NORCO"."UNITS_SNAPSHOT" AS US2 WHERE US1.CCODE=US2.CCODE)
and
SELECT *
FROM "NORCO"."UNITS_SNAPSHOT" AS US1
WHERE US1.CCODE LIKE '%514-L%' AND
US1.TIMESTAMP=LAST_DAY(US1.TIMESTAMP,'MONTH')
What I expect for the return from the daily records table is the last day of month records. Suggestions, help or ideas are appreciated!!
Thanks all

I would be sure that the data types are identical, ie. DATE, so a minor change:
SELECT *
FROM "NORCO"."UNITS_SNAPSHOT" AS US1
WHERE US1.CCODE LIKE '%514-L%' AND
US1.TIMESTAMP::DATE=(SELECT LAST_DAY(US1.TIMESTAMP, MONTH)
FROM "NORCO"."UNITS_SNAPSHOT" AS US2 WHERE US1.CCODE=US2.CCODE)
I have a hard time understanding what this query is trying to achieve and why it has to be correlated. Is it to look for a set of CCODE that have a TIMESTAMP of EOM? If that is the case, some simplification:
SELECT *
FROM "NORCO"."UNITS_SNAPSHOT" AS us
WHERE us.CCODE LIKE '%514-L%' AND
us."TIMESTAMP"::DATE=LAST_DAY(us."TIMESTAMP", MONTH)

Related

How to execute SELECT DISTINCT ON query using SQLAlchemy

I have a requirement to display spend estimation for last 30 days. SpendEstimation is calculated multiple times a day. This can be achieved using simple SQL query:
SELECT DISTINCT ON (date) date(time) AS date, resource_id , time
FROM spend_estimation
WHERE
resource_id = '<id>'
and time > now() - interval '30 days'
ORDER BY date DESC, time DESC;
Unfortunately I can't seem to be able to do the same using SQLAlchemy. It always creates select distinct on all columns. Generated query does not contain distinct on.
query = session.query(
func.date(SpendEstimation.time).label('date'),
SpendEstimation.resource_id,
SpendEstimation.time
).distinct(
'date'
).order_by(
'date',
SpendEstimation.time
)
SELECT DISTINCT
date(time) AS date,
resource_id,
time
FROM spend
ORDER BY date, time
It is missing ON (date) bit. If I user query.group_by - then SQLAlchemy adds distinct on. Though I can't think of solution for given problem using group by.
Tried using function in distinct part and order by part as well.
query = session.query(
func.date(SpendEstimation.time).label('date'),
SpendEstimation.resource_id,
SpendEstimation.time
).distinct(
func.date(SpendEstimation.time).label('date')
).order_by(
func.date(SpendEstimation.time).label('date'),
SpendEstimation.time
)
Which resulted in this SQL:
SELECT DISTINCT
date(time) AS date,
resource_id,
time,
date(time) AS date # only difference
FROM spend
ORDER BY date, time
Which is still missing DISTINCT ON.
Your SqlAlchemy version might be the culprit.
Sqlalchemy with postgres. Try to get 'DISTINCT ON' instead of 'DISTINCT'
Links to this bug report:
https://bitbucket.org/zzzeek/sqlalchemy/issues/2142
A fix wasn't backported to 0.6, looks like it was fixed in 0.7.
Stupid question: have you tried distinct on SpendEstimation.date instead of 'date'?
EDIT: It just struck me that you're trying to use the named column from the SELECT. SQLAlchemy is not that smart. Try passing in the func expression into the distinct() call.

Calculate the sum of time column in PostgreSql

Can anyone suggest me, the easiest way to find summation of time field in POSTGRESQL. i just find a solution for MYSQL but i need the POSTGRESQL version.
MYSQL: https://stackoverflow.com/questions/3054943/calculate-sum-time-with-mysql
SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(timespent))) FROM myTable;
Demo Data
id time
1 1:23:23
2 4:00:23
3 9:23:23
Desired Output
14:47:09
What you want, is not possible. But you probably misunderstood the time type: it represents a precise time-point in a day. It doesn't make much sense, to add two (or more) times. f.ex. '14:00' + '14:00' = '28:00' (but there are no 28th hour in a day).
What you probably want, is interval (which represents time intervals; hours, minutes, or even years). sum() supports interval arguments.
If you use intervals, it's just that simple:
SELECT sum(interval_col) FROM my_table;
Although, if you stick to the time type (but you have no reason to do that), you can cast it to interval to calculate with it:
SELECT sum(time_col::interval) FROM my_table;
But again, the result will be interval, because time values cannot exceed the 24th hour in a day.
Note: PostgreSQL will even do the cast for you, so sum(time_col) should work too, but the result is interval in this case too.
I tried this solution on sql fieddle:
link
Table creation:
CREATE TABLE time_table (
id integer, time time
);
Insert data:
INSERT INTO time_table (id,time) VALUES
(1,'1:23:23'),
(2,'4:00:23'),
(3,'9:23:23')
query the data:
SELECT
sum(s.time)
FROM
time_table s;
If you need to calculate sum of some field, according another field, you can do this:
select
keyfield,
sum(time_col::interval) totaltime
FROM myTable
GROUP by keyfield
Output example:
keyfield; totaltime
"Gabriel"; "10:00:00"
"John"; "36:00:00"
"Joseph"; "180:00:00"
Data type of totaltime is interval.

PostgresSQL database has date field, I want all data but the date column as year only

I have data that has a date column in the full format but would like the output to only represent the year.
eg: from
SELECT * FROM tablename;
I want something like:
SELECT * FROM tablename WITH 'newdatefield' as SELECT EXTRACT(YEAR FROM TIMESTAMP 'datefield');
I'm not great at SQL - I remember that something like this can be done but can't find how to do it again.
I think you are overthinking this one:
SELECT EXTRACT(YEAR from datefield), The, Other, Fields, You, Want FROM tableName

To Pull records between two dates in db2

I tried below two ways they not working
Select * from Table
where SERV_DATE BETWEEN '03/01/2013'AND
'03/31/2013'
ALSO This is not working
Select * from Table
where SERV_DATE BETWEEN DATE('03/01/2013') AND
DATE('03/31/2013')
What should be the correct format ?
Did you tried what NealB suggested? The reason for not accepting 03/01/2013 as an entry date format is, that it is region dependent in the US it is March 1, 2013 an in the UK it is January 3, 2013. So without considering the local, it is not certain, what the actual date is.
"why would db2 give error on the same format and will go well when given different format" - Don't forget, that db2 is an old lady and as all old ladies she has peculiarities. You just get used to it and there will be an happy ending.
SELECT * FROM tableName WHERE date(modifiedBy_date) between '2017-07-28' AND '2017-08-01';
Works cool for DB2.
Select * from Table
where SERV_DATE BETWEEN DATE('2013-03-01') AND DATE('2013-03-31');
Worked for me.
Select * from Table
where (SERV_DATE BETWEEN '03/01/2013'AND
'03/31/2013')
Select * from Table
where (SERV_DATE BETWEEN '2013-03-01'AND
'2013-03-31')
select count(*) from TABLE where time_stamp BETWEEN DATE('2018-01-01') AND DATE('2018-01-31');
Here time_stamp is field name and copy your timestamp filed name instead of time_stamp.

psql 8.4.1 select all the person born in a specific month

I am supposed to select all the persons born in July (or 07). This did not work:
select * from people where date_trunc('month',dob)='07';
ERROR: invalid input syntax for type timestamp with time zone: "07"
LINE 1: ...ct * from people where date_trunc('month',dob)='07';
What is the right way?
to_char() is meant to format dates. For a condition like yours, extract() is simpler & faster:
SELECT *
FROM people
WHERE extract(month FROM dob) = 7;
If you want to search for
a specific year and month too (YYYY-MM)
... like mentioned in the comment, use date_trunc() like you had initially. Just compare it to a date or timestamp, not to a string, which wouldn't make any sense (and was the cause of the error message). To find people born July 1970:
SELECT *
FROM people
WHERE date_trunc('month', dob) = '1970-07-01 0:0'::timestamp;
If performance is relevant, rewrite that to:
SELECT *
FROM people
WHERE dob >= '1970-07-01 0:0'::timestamp
AND dob < '1970-08-01 0:0'::timestamp; -- note the < with the upper limit
Because this form can use a plain index on people.dob:
CREATE INDEX people_dob_idx ON people (dob);
... and will therefore nuke the performance of the previous queries with big tables. Doesn't matter much with small tables.
You could also speed up the first query with a functional index, if needed.
select * from people where to_char(dob, 'MM') = '09';
gives you all people who where born in September, if the date of birth is stored in a timestamp table column called 'dob'.
The second param is the date format pattern. All typical patterns should be supported.
E.g.:
select * from people where to_char(dob, 'MON') = 'SEP';
would do the same.
look here for timestamp format patterns in Postgres: