I want to find out what is the average number from table column entries (for example reservations) per year(0-10 years ago, 10-20 years ago, 20+ years ago). I know how to do the average part but I don't know how to categorize the AVG in the different group years.
i have this code
SELECT DATE_OF_RESERVATION,count(RESERVATIONID) AS RESERVATIONS
FROM RESERVATIONS
WHERE EXTRACT(YEAR FROM Current_Date) - DATE_OF_RESERVATION <= 10
GROUP BY DATE_OF_RESERVATION
This is the code for only one category (the first). I want to do this for all three at the same query but I can't figure it out.
You can use a case expression. For instance:
SELECT (CASE WHEN EXTRACT(YEAR FROM Current_Date) - DATE_OF_RESERVATION < 10
THEN '[0-10)'
WHEN EXTRACT(YEAR FROM Current_Date) - DATE_OF_RESERVATION < 20
THEN '[0-20)'
WHEN EXTRACT(YEAR FROM Current_Date) - DATE_OF_RESERVATION < 30
THEN '[0-30)'
ELSE 'More'
END) as grp,
COUNT(*) AS RESERVATIONS
FROM RESERVATIONS
GROUP BY grp;
Related
Can anyone describe how can I suppose to retrieve data using filter conditions such as both where and group by clauses of different fields through SQL ?
For instance ,
Require to take out the No of days in a month does the temperature exceeding 35 degrees celsius ?
SELECT temp, count(*)
FROM weather_data
WHERE day between '01-jun-2022' to '30-jun-2022'
GROUP BY temp > '35';
My requirement is to find out the aggregate details like total count
So I tried using group by clause , Inaddition to that , I must use few conditions to filter further ,
Hence I used conditions in where clause before group by clause
it's correct query :
SELECT temp, count(*) FROM weather_data
WHERE temp > '35' AND day between '01-jun-2022' and '30-jun-2022' GROUP BY temp
You want to aggregate your data, so as to get one result row per month. In SQL this is GROUP BY EXTRACT(YEAR FROM day), EXTRACT(MONTH FROM day). Your DBMS may have additional functions to extract a month (year + month to be precise) from a date, such as TO_CHAR(day, 'YYYY-MM'), but this is vendor specific.
Now you only want to count days with a temperature obove 35 degrees. The first idea to solve this, is a WHERE clause that limits the rows you aggregate to the ones in question:
SELECT
EXTRACT(YEAR FROM day) AS year,
EXTRACT(MONTH FROM day) AS month,
COUNT(*)
FROM mytable
WHERE temp > 35
GROUP BY EXTRACT(YEAR FROM day), EXTRACT(MONTH FROM day)
ORDER BY EXTRACT(YEAR FROM day), EXTRACT(MONTH FROM day);
The problem with this: If a month has no day above that temperature, you won't select that month, because your WHERE clause removed those rows. That may be okay with you, but if you want to show the months with a zero count, then move the condition into the aggregation function. Thus you select all months but only count days with high temperatures:
SELECT
EXTRACT(YEAR FROM day) AS year,
EXTRACT(MONTH FROM day) AS month,
COUNT(CASE WHEN temp > 35 THEN 1 END)
FROM mytable
GROUP BY EXTRACT(YEAR FROM day), EXTRACT(MONTH FROM day)
ORDER BY EXTRACT(YEAR FROM day), EXTRACT(MONTH FROM day);
How does this work? COUNT <expression> ) counts non-null occurrences. CASE WHEN temp > 35 THEN 1 END is short for CASE WHEN temp > 35 THEN 1 ELSE NULL END. And instead of 1 you could use any value that is not null, e.g. 'count me'. Or you could use SUM instead, if you like that better: SUM(CASE WHEN temp > 35 THEN 1 ELSE 0 END).
At last you want to limit the date range. Date literals in SQL look like this: DATE 'YYYY-MM-DD'. And as we sometimes deal with dates and other times with datetimes or timestamps, it has become common, not to use BETWEEN, but >= and <, so as to have the range work for all those data types:
SELECT
EXTRACT(YEAR FROM day) AS year,
EXTRACT(MONTH FROM day) AS month,
COUNT(CASE WHEN temp > 35 THEN 1 END)
FROM mytable
WHERE day >= DATE '2022-06-01'
AND day < DATE '2022-07-01'
GROUP BY EXTRACT(YEAR FROM day), EXTRACT(MONTH FROM day)
ORDER BY EXTRACT(YEAR FROM day), EXTRACT(MONTH FROM day);
Try this:
SELECT temp, count(*)
FROM weather_data
WHERE date >= '01-jun-2022' AND date<='30-jun-2022' AND temp > '35'
GROUP BY temp;
I'm trying to exclude the Christmas period between two dates every year in my database. This is the query I'm trying to run. From my understanding this should include every row, for every year with the exception of rows where the month is <= 12 and day <= 15 and where the month is <= 12 and day >= 26.
The result, however, doesn't appear to return any rows at all!
SELECT
*
FROM
transactons
WHERE
event_date BETWEEN TO_DATE("2016-12-01")
AND TO_DATE("2021-12-31")
AND ((EXTRACT(MONTH FROM event_date) <= 12 AND EXTRACT(DAY FROM event_date) <= 15)
AND (EXTRACT(MONTH FROM event_date) <= 12 AND EXTRACT(DAY FROM event_date) >= 26))
Does anyone have any suggestions as to how to filter out Dec-15 to Dec-26 each year here?
You should specify your DBMS, because the following code can change. Please provide it and I will glade to update my answer.
For something quick and if I understand your logic:
SELECT
*
FROM
transactons
WHERE
(
MONTH(event_date) = 12
AND
DAY(event_date) BETWEEN 12 AND 26
)
You can reverse the query if you put NOT after the WHERE
I am writing a query that counts trips which exceed 20 minutes but is only in the years 2015, 2016, 2017. The code works fine, showing the years and number of trips per year, but the results show all years and not just these three. The issue is that the column start_time is a timestamp. I can do timestamp_add and then between (as shown below, disregard the number of days as they are just placeholders) but it just seems sloppy
I can do timestamp_add and then between (as shown below, disregard the number of days as they are just placeholders) but it just seems sloppy.
SELECT extract(year from start_time), count(*)
FROM `datapb.shopping.trips`
where duration_minutes > 20 and
start_time between timestamp_add(current_timestamp(), interval -1000 DAY) AND timestamp_add(current_timestamp(), interval -350 DAY)
group by EXTRACT(YEAR from start_time)
Any suggestions would be fantastic, thanks!
Why not just use timestamp constants?
select extract(year from start_time) as yyyy, count(*)
from `datapb.shopping.trips`
where duration_minutes > 20 and
start_time >= timestamp('2015-01-01') and
start_time < timestamp('2018-01-01')
group by yyyy
order by yyyy;
I'm looking to write a query that returns a result set of accounts that have ordered at least 250 dollars each month for six consecutive months. Any guidance would be greatly appreciated.
SELECT DATE_TRUNC ('month',order_date)::date as order_month
,account_name
,account_id
,SUM(order_amount) as monthly_spend
FROM order_table
WHERE order_date::date >= current_date - interval '6 months'
GROUP BY 1,2,3
Those that have ordered at least $250 dollars each month for the last six consecutive months.
Aggregation comes to mind. Let me also align the months with the calendar months (that seems like the most likely interpretation of "last six months").
The idea is to filter down to the months that are >= $250 and then be sure there are six of them.
SELECT account_name, account_id, COUNT(*) as num_months,
SUM(monthly_spend) as total_spend
FROM (SELECT DATE_TRUNC('month', order_date)::date as order_month,
account_name, account_id, SUM(order_amount) as monthly_spend
FROM order_table
WHERE order_date::date >= date_trunc('month', current_date) - interval '6 months' AND
order_date::date < date_trunc('month', current_date)
GROUP BY 1, 2, 3
HAVING monthly_spend >= 250
) ma
GROUP BY 1, 2
HAVING COUNT(*) = 6;
I've been at this problem for an assignment for a few days now and I haven't been able to get a correct query to work. My instructor has been less than helpful. The question is as follows:
"You are asked to prepare a list of employee anniversaries that occur between two days ago and seven days from now. The list should retrieve rows from the EMPLOYEES table which include the EMPLOYEE_ID, FIRST_NAME, LAST_NAME, JOB_ID, and HIRE_DATE columns in ascending order based on the day and month components of the HIRE_DATE value. An additional expression aliased as ANNIVERSARY is required to return a descriptive message based on the following table. There are several approaches to solving this question.
HIRING DAY-------------------------MESSAGE
Two days ago------------------------Day before yesterday
One day ago-------------------------Yesterday
Today----------------------------------Today
Tomorrow-----------------------------Tomorrow
Two days in the future--------------Day after tomorrow
Within seven days from today----Later this week
Hint: Use CASE/WHEN, TO_CHAR AND TO_NUMBER FUNCTIONS
Your results will vary depending on which date you execute the query."
I have been able to come up with the following query but it does not take into account when it is the end of the year and the anniversary is in early January:
SELECT EMPLOYEE_ID, FIRST_NAME, LAST_NAME, JOB_ID, HIRE_DATE,
CASE WHEN TO_DATE(TO_CHAR(HIRE_DATE,'DDMM'),'DDMM') - TRUNC(SYSDATE) = -2 THEN 'Day before yesterday'
WHEN TO_DATE(TO_CHAR(HIRE_DATE,'DDMM'),'DDMM') - TRUNC(SYSDATE) = -1 THEN 'Yesterday'
WHEN TO_DATE(TO_CHAR(HIRE_DATE,'DDMM'),'DDMM') - TRUNC(SYSDATE) = 0 THEN 'Today'
WHEN TO_DATE(TO_CHAR(HIRE_DATE,'DDMM'),'DDMM') - TRUNC(SYSDATE) = 1 THEN 'Tomorrow'
WHEN TO_DATE(TO_CHAR(HIRE_DATE,'DDMM'),'DDMM') - TRUNC(SYSDATE) = 2 THEN 'Day after tomorrow'
WHEN TO_DATE(TO_CHAR(HIRE_DATE,'DDMM'),'DDMM') - TRUNC(SYSDATE) BETWEEN 2 AND 7 THEN 'Later this week'
ELSE TO_CHAR(HIRE_DATE, 'MON-DD')
END
AS "ANNIVERSARY"
FROM EMPLOYEES
ORDER BY TO_CHAR(HIRE_DATE, 'MMDD');
Any help would be greatly appreciated! Thank you!
The CASE expressions come into two flavors:
Simple case expression: CASE expr WHEN value THEN result WHEN value THEN result ...
Searched case expression: CASE WHEN condition THEN result WHEN cond THEN result ...
I am combining both, one returning the number of day difference (inner). This result is used as expression in the second (outer) case expression which determins the message.
The inner case expression handles two edge cases at year boundaries and one normal case.
SELECT CASE
CASE WHEN EXTRACT(MONTH FROM SYSDATE) = 1 AND EXTRACT(MONTH FROM HIRE_DATE) = 12 THEN
MAKEDATE(EXTRACT(YEAR FROM SYSDATE)-1 12 EXTRACT(DAY FROM HIRE_DATE)) - TRUNC(SYSDATE)
WHEN EXTRACT(MONTH FROM SYSDATE) = 12 AND EXTRACT(MONTH FROM HIRE_DATE) = 1 THEN
MAKEDATE(EXTRACT(YEAR FROM SYSDATE)+1 1 EXTRACT(DAY FROM HIRE_DATE)) - TRUNC(SYSDATE)
ELSE
MAKEDATE(EXTRACT(YEAR FROM SYSDATE) EXTRACT(MONTH FROM HIRE_DATE) EXTRACT(DAY FROM HIRE_DATE)) -
TRUNC(SYSDATE)
END
WHEN -2 THEN '...'
WHEN -1 THEN '...'
...
ELSE ...
END