How to create a view in PostgreSQL with where clause - sql

I am trying to create a view in Postgres
I have 3-4 time stamps in each closing_date where I need to select only the latest time stamp of each day
And also I have to restrict the closing_date to only 30 days (shown in SQL query below)
Below is the query from SQL data which I had created
CREATE VIEW dbo.CashBreaks_30Days_View as
SELECT Closing_date,Bo,Desk,Breaks_Staus,Owner,status,Team,
SLA,Age_Bucket_EntryDate,Age_Bucket_ValueDate,Age_EntryDate,Age_ValueDate,
[Type_(2)]
FROM Master_Data_CashBreaks
WHERE Closing_date >= cast(getdate()-37 as date);

If I understood you correctly, something like this might return result you want:
create or replace view cash_breaks_30days_view
as
select a.list_of_columns
from master_data_cashbreaks a
where a.closing_date >= trunc(sysdate) - 30 --> the last 30 days
and a.closing_date = (select max(b.closing_date) --> subquery is used to return
from master_data_cashbreaks b -- the last timestamp per date
where b.id = a.id
and trunc(b.closing_date) = trunc(a.closing_date)
)

There are few mistakes in your code:
[Type_(2)] - Not a valid SQL
getdate() - There is no such function available in Oracle. you should use the trunc(SYSDATE) instead.
getdate()-37 - Why -37, when you want the last 30 days data. It should be 30.
Your query should look like this in oracle:
CREATE VIEW dbo.CashBreaks_30Days_View as
SELECT * FROM
(SELECT Closing_date,Bo,Desk,Breaks_Staus,Owner,status,Team,
SLA,Age_Bucket_EntryDate,Age_Bucket_ValueDate,Age_EntryDate,Age_ValueDate,
ROW_NUMBER() OVER (PARTITION BY Closing_date ORDER BY Closing_date DESC) AS RN
FROM Master_Data_CashBreaks
WHERE Closing_date >= TRUNC(SYSDATE) - 30)
WHERE RN = 1;

Your SQL contains a lot of errors
square brackets are invalid in SQL identifiers, if you have such a column you need to use double quotes. It's unclear to me if your column is named "[Type_(2)]" or maybe just `"Type_(2)"
There is no getdate() in SQL or in Postgres. Use current_date instead
So fixing all those error, your statement should look like this:
CREATE VIEW dbo.CashBreaks_30Days_View
as
SELECT Closing_date, Bo, Desk, Breaks_Staus, Owner, status,
Team, SLA, Age_Bucket_EntryDate,
Age_Bucket_ValueDate, Age_EntryDate, Age_ValueDate,
"[Type_(2)]" -- or maybe only "Type_(2)"
FROM Master_Data_CashBreaks
WHERE Closing_date >= current_cate - 30;

i am able to create with the below
create or replace view cashbreaks_30days_view_latesttime
as
select a. Column details
from master_data a
where a. Closing_date >= NOW() - interval '40 days'
and a.closing_date = (select max(b.closing_date)
from master_data b
where date(b.closing_date) = date(a.closing_date));

Related

Dynamic date in BigQuery

Without manually having to change the date to current date, I'd like to have code which helps to change the date automatically or auto increment date by one day post 0000hrs in big query
AND ((call_date >= "2022-10-01") AND (call_date <= "2022-10-12"))
Below is the complete code.
WITH_0 AS ( SELECT *, FROM employee_calldata),
_1 AS (
SELECT
call_date AS __call_date__1,
sub_queue AS __sub_queue__1,
sum(call_count) as callstaken,
mode AS __mode__1, `FROM _0 AS _t
WHERE
(NOT ((call_type) IS NULL)))
AND ((call_date >= "2022-10-01") AND (call_date <= "2022-10-12"))
AND (sub_queue = "Customer_Complaints")
GROUP BY __call_date__1, __sub_queue__1, __mode__1)
SELECT * FROM _1
`
DATE((DATETIME_ADD(('2022-10-03 00:00:00'), INTERVAL 100 HOUR)))
=> 2022-10-07
I think what you are asking is how you can create rolling windows that increment as the days go forward.
The equivalent to:
AND ((DATE(call_date) >= "2022-10-01") AND (call_date <= "2022-10-12"))
Is:
AND ((DATE(call_date) >= DATETIME_SUB(CURRENT_DATE(), INTERVAL 2 DAY) AND (DATE(call_date) <= DATETIME_ADD(CURRENT_DATE(), INTERVAL 9 DAY)
These values will change based on the current date, change the intervals in DATETIME_SUB and DATETIME_ADD to change the difference from the current date.
Also some other general comments on your code.
You do not need brackets on the WHERE conditions.
(NOT ((call_type) IS NULL))) can be written as call_type IS NOT NULL.
You do not need your first SELECT *, FROM employee_calldata or your SELECT * FROM _1 as they do nothing extra.
This means your final query can be written as:
SELECT
call_date AS __call_date__1,
sub_queue AS __sub_queue__1,
sum(call_count) as callstaken,
mode AS __mode__1
FROM
employee_calldata AS _t
WHERE
call_type IS NOT NULL
AND DATE(call_date) >= DATETIME_SUB(CURRENT_DATE(), INTERVAL 2 DAY)
AND DATE(call_date) <= DATETIME_ADD(CURRENT_DATE(), INTERVAL 9 DAY)
AND sub_queue = "Customer_Complaints"
GROUP BY
__call_date__1,
__sub_queue__1,
__mode__1

tdate issue I'm facing in SQL query

While fetching count from table by using following query
Select count(*)
from tab
where tdate = '17-05-19' ---> output 0
or
Select count(*)
from tab
where trunc(tdate) = '17-05-19' ---->output 0
If I use:
Select count(*)
from tab
where tdate >sysdate - 1 ---> it returns some count(yesterday+some of the today txn)
But here I want only yesterday txn whenever I fire this query.
But here I want only yesterday txn whenever I fire this query.
You may use this.
Select count (*) from tab where
tdate >= TRUNC(SYSDATE) - 1
AND tdate < TRUNC(SYSDATE)
The advantage of this over using TRUNC on the date column is that it will utilize an index if it exists over tdate
If you tried by using
Select count(*) from tab where trunc(tdate) = date'2019-05-17'
(or, you could use
Select count(*) from tab where to_char(tdate,'dd-mm-yy') = '17-05-19' by formatting through to_char function
or, you could use
Select count(*) from tab where trunc(tdate) = trunc(sysdate)-1 to get only the data for the day before
)
you'd get some results provided you have data for the date 17th May.
So, you need to provide a formatting for your literal as date'2019-05-17'(known as date literal) especially for Oracle DB, it might be used as '2019-05-17' without date part in MySQL as an example.
Btw, trunc function is used to extract the date portion, and remove the time part of a date type column value.
If your table is populated with huge data, therefore performance may matter, then you can even create functional index on trunc(tdate).
Demo

sql query to get today new records compared with yesterday

i have this table:
COD (Integer) (PK)
ID (Varchar)
DATE (Date)
I just want to get the new ID's from today, compared with yesterday (the ID's from today that are not present yesterday)
This needs to be done with just one query, maximum efficiency because the table will have 4-5 millions records
As a java developer i am able to do this with 2 queries, but with just one is beyond my knowledge so any help would be so much appreciated
EDIT: date format is dd/mm/yyyy and every day each ID may come 0 or 1 times
Here is a solution that will go over the base data one time only. It selects the id and the date where the date is either yesterday or today (or both). Then it GROUPS BY id - each group will have either one or two rows. Then it filters by the condition that the MIN date in the group is "today". Those are the id's that exist today but did not exist yesterday.
DATE is an Oracle keyword, best not used as a column name. I changed that to DT. I also assume that your "dt" field is a pure date (as pure as it can be in Oracle, meaning: time of day, which is always present, is 00:00:00).
select id
from your_table
where dt in (trunc(sysdate), trunc(sysdate) - 1)
group by id
having min(dt) = trunc(sysdate)
;
Edit: Gordon makes a good point: perhaps you may have more than one such row per ID, in the same day? In that case the time-of-day may also be different from 00:00:00.
If so, the solution can be adapted:
select id
from your_table
where dt >= trunc(sysdate) - 1 and dt < trunc(sysdate) + 1
group by id
having min(dt) >= trunc(sysdate)
;
Either way: (1) the base table is read just once; (2) the column DT is not wrapped within any function, so if there is an index on that column, it can be used to access just the needed rows.
The typical method would use not exists:
select t.*
from t
where t.date >= trunc(sysdate) and t.date < trunc(sysdate + 1) and
not exists (select 1
from t t2
where t2.id = t.id and
t2.date >= trunc(sysdate - 1) and t2.date < trunc(sysdate)
);
This is a general solution. If you know that there is at most one record per day, there are better solutions, such as using lag().
Use MINUS. I suppose your date column has a time part, so you need to truncate it.
select id from mytable where trunc(date) = trunc(sysdate)
minus
select id from mytable where trunc(date) = trunc(sysdate) - 1;
I suggest the following function index. Without it, the query would have to full scan the table, which would probably be quite slow.
create idx on mytable( trunc(sysdate) , id );

Help me build a SQL select statement

SQL isn't my greatest strength and I need some help building a select statement.
Basically, this is my requirement. The table stores a list of names and a timestamp of when the name was entered in the table. Names may be entered multiple times during a week, but only once a day.
I want the select query to return names that were entered anytime in the past 7 days, but not today.
To get a list of names entered today, this is the statement I have:
Select * from table where Date(timestamp) = Date(now())
And to get a list of names entered in the past 7 days, not including today:
Select * from table where (Date(now())- Date(timestamp) < 7) and (date(timestamp) != date(now()))
If the first query returns a set or results, say A, and the second query returns B, how can I get
B-A
Try this if you're working with SQL Server:
SELECT * FROM Table
WHERE Timestamp BETWEEN
dateadd(day,datediff(day,0,getdate()),-7),
AND dateadd(day,datediff(day,0,getdate()),0)
This ensures that the timestamp is between 00:00 7 days ago, and 00:00 today. Today's entries with time greater than 00:00 will not be included.
In plain English, you want records from your second query where the name is not in your first query. In SQL:
Select *
from table
where (Date(now())- Date(timestamp) < 7)
and (date(timestamp) != date(now()))
and name not in (Select name
from table
where Date(timestamp) = Date(now())
)
not in
like
select pk from B where PK not in A
or you can do something like
Select * from table where (Date(now())- Date(timestamp) < 7) and (Date(now())- Date(timestamp) > 1)

Add year to column before compare in SQL query

I am querying a MySQL database and I need to add a year to a column (of type date) before the compare operation.
I would expect is to look something like this:
SELECT count(*) AS count
FROM users
WHERE renewed + 1 year < '2009-12-12'
Use:
SELECT COUNT(*) AS count
FROM USERS u
WHERE DATE_ADD(u.renewed, INTERVAL 1 YEAR) < '2009-12-12'
Reference:
DATE_ADD
You can use the mysql DATE_ADD function:
DATE_ADD(renewed, INTERVAL 1 YEAR)