Exclude dates within a range in SQL/Big Query - sql

I am trying to exclude any data that has more than 10 days between Min_Sort_Date and Max_Sort_Date.
This is the initial query I have to start with:
select
srt_bin_id,
Min(srt_cred_tmst) as Min_Sort_Date,
Max(srt_cred_tmst)as Max_Sort_Date,
Count(trkg_id) as count_of_packages,
Max(srt_loc_id) as Store
from bda-prd.dp_logistics.bqt_lgs_rets_rpt
where srt_cred_tmst > "2022-08-13"
Group by 1
Any tips on where to go from here?

If my memory is good, you can use DATE_DIFF function with BigQuery to do something like:
select
DATE_DIFF(Max(srt_cred_tmst), Min(srt_cred_tmst), DAY) AS DAYS_GAP from
Database.Table
Like that you will be able to calculate the gap, and exclude rows with a where condition when DAYS_GAP >= 10

Related

Unable to divide to counts of two separate lists in SQL, keeps returning 1

I have one list of events. One event name is creating an account and another is creating an account with Facebook. I am trying to see what percentage of accounts created use Facebook.
The code below will give me an accurate count of the number of facebook accounts and total accounts, but when I try to divide the two numbers it just gives me the number 1.
I am very new to SQL, and have spent hours trying to figure out why it is doing that to no avail.
with
fb_act as (
select *
from raw_event
where name = 'onboard_fb_success'
and event_ts::date >= current_date - 30
),
total_act as (
select *
from raw_event
where name ='create_account'
and event_ts::date >= current_date - 30
)
select count(fb_act)/count(total_act), total_act.event_ts::date as day
from total_act, fb_act
group by day
order by day
I expect the output to be about ~.3, but the actual output is always exactly 1.
Conditional aggregation is a much simpler way to write the query. You appear to be using Postgres, so something like this:
select re.event_ts::date as day,
(sum( (name = 'onboard_fb_success' and event_ts::date >= current_date - 30):: int) /
sum( name = 'create_account' and event_ts::date >= current_date - 30)::int)
) as ratio
from raw_event re
group by re.event_ts::date
order by day;

Calculating aggregated field

I'm back with more potgresql question :)
I have a query that shows the amount of time between when a plan was created and when a plan was updated.
select
...
EXTRACT(DAY FROM MAX(plans.updated_at) - MIN(plans.created_at)) AS DateDifference
...
Now I would like to exclude the results when the number of days is 0
So I tried:
WHERE EXTRACT(DAY FROM MAX(plans.updated_at) - MIN(plans.created_at)) > 0
But I get Aggregated functions are not allowed in where.
What would be the best way to accomplish this?
Thanks in advance
If your query does what you want, then you would use a having clause:
HAVING EXTRACT(DAY FROM MAX(plans.updated_at) - MIN(plans.created_at)) > 0
Conditions on aggregated values need to be handled after the aggregation. Hence, the HAVING clause goes after the GROUP BY.

SELECT statement optimization

I'm not so expert in SQL queryes, but not even a complete newbie.
I'm exporting data from a MS-SQL database to an excel file using a SQL query.
I'm exporting many columns and two of this columns contain a date and an hour, this are the columns I use for the WHERE clause.
In detail I have about 200 rows for each day, everyone with a different hour, for many days. I need to extract the first value after the 15:00 of each day for more days.
Since the hours are different for each day i can't specify something like
SELECT a,b,hour,day FROM table WHERE hour='15:01'
because sometimes the value is at 15:01, sometimes 15:03 and so on (i'm looking for the closest value after the 15:00), for fix this i used this workaround:
SELECT TOP 1 a,b,hour,day FROM table WHERE hour > "15:00"
in this way i can take the first value after the 15:00 for a day...the problem is that i need this for more days...for a user-specifyed interval of days. At the moment i fix this with a UNION ALL statement, like this:
SELECT TOP 1 a,b,hour,day FROM table WHERE data="first_day" AND hour > "15:00"
UNION ALL SELECT TOP 1 a,b,hour,day FROM table WHERE data="second_day" AND hour > "15:00"
UNION ALL SELECT TOP 1 a,b,hour,day FROM table WHERE data="third_day" AND hour > "15:00"
...and so on for all the days (i build the SQL string with a for each day in the specifyed interval).
Until now this worked, but now I need to expand the days interval (now is maximun a week, so 5 days) to up to 60 days. I don't want to build an huge query string, but i can't imagine an alternative way for write the SQL.
Any help appreciated
Ettore
I typical solution for this uses row_number():
SELECT a, b, hour, day
FROM (SELECT t.*,
ROW_NUMBER() OVER (PARTITION BY day ORDER BY hour) as seqnum
FROM table t
WHERE hour > '15:00'
) t
WHERE seqnum = 1;

SQL to filter for records more than 30 days old

Suppose I have the following query:
select customer_name, origination_date
where origination_date < '01-DEC-2013';
I would like to select all customers that have an origination date older than 30 days. Is there a way in SQL (oracle, if specifics needed) to specify it in a more dynamic approach than manually entering the date so that I don't need to update the query every time I run it?
Thanks!
Sure try something like this:
select customer_name, origination_date where
origination_date >= DATEADD(day, -30, GETUTCDATE());
This basically says where the origination_date is greater or equal to 30 days from now. This works in Microsoft SQL, not sure but there is probably a similar function on Oracle.
in Oracle, when you subtract dates, by default you get the difference in days, e.g.
select * from my_table where (date_1 - date_2) > 30
should return the records whose date difference is greater than 30 days.
To make your query dynamic, you parameterize it, so instead of using hard coded date values, you use:
select * from my_table where (:date_1 - :date_2) > :threshold
If you are using oracle sql developer to run such a query, it will pop up a window for you to specify the values for your paramteres; the ones preceded with colon.

mysql return rows matching year month

How would I go about doing a query that returns results of all rows that contain dates for current year and month at the time of query.
Timestamps for each row are formated as such: yyyy-mm-dd
I know it probably has something to do with the date function and that I must somehow set a special parameter to make it spit out like such: yyyy-mm-%%.
Setting days to be wild card character would do the trick but I can't seem to figure it out how to do it.
Here is a link to for quick reference to date-time functions in mysql:
http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html
Thanks
I think EXTRACT is the function you are looking for:
SELECT * FROM table
WHERE EXTRACT(YEAR_MONTH FROM timestamp_field) = EXTRACT(YEAR_MONTH FROM NOW())
you could extract the year and month using a function, but that will not be able to use an index.
if you want scalable performance, you need to do this:
SELECT *
FROM myTable
WHERE some_date_column BETWEEN '2009-01-01' AND '2009-01-31'
select * from someTable where year(myDt) = 2009 and month(myDt) = 9 and day(myDt) = 12