Subtracting dates in SQL Big Query - sql

I'm sure this is super simple, but I am still very new to SQL. I am trying to subtract two dates, but one date is just a birthyear in an integer format and the other I would like for it to be the current date. I am trying to find age of these individuals. Any help would be greatly appreciated! What i have so far is below. Thank you!
select
distinct(count(usertype)),
gender, usertype,
date_diff(extract(year from current_date) as current_year, tripdata.birth_year, year)
from `project-1-349215.Dataset.tripdata`

Posting #JNevill's suggestion in the comment section as wikianswer:
with tripdata as (
select 1995 as birth_year, "premium" as usertype, "F" as gender,
union all select 1990 as birth_year, "standard" as usertype, "F" as gender,
union all select 1990 as birth_year, "standard" as usertype, "F" as gender,
union all select 1993 as birth_year, "standard" as usertype, "F" as gender,
union all select 1993 as birth_year, "premium" as usertype, "M" as gender,
union all select 1994 as birth_year, "premium" as usertype, "F" as gender,
)
select
count(usertype),
gender,
extract(year from current_date) - tripdata.birth_year as age
from tripdata
group by usertype, gender, tripdata.birth_year;
Output:

date_diff(Column1,column2,day) As date_diff_days
if you want to perform difference in minute and seconds --> change day to minute and seconds.

Related

Age In Years Of Youngest Employee

I have a table called employees and I I need to get the age of the youngest employee in years.
For example if I look at the table the youngest employee is "57 years old"
The columns:
EmployeeID, Lastname, Title, Birthdate, Hiredate, City, Country
The code I was trying was this:
SELECT MAX(birthdate)
FROM employees;
With that I can get the date of birth of the youngest employee, but now I need to somehow compare it with the current date that would be using "sysdate" and then change it to numbers so that it shows that he is 57 years old, but I have not succeeded
You can use:
SELECT TRUNC(MONTHS_BETWEEN(SYSDATE, MAX(birthdate))/12) AS age
FROM employees;
Which, for the sample data:
CREATE TABLE employees ( id, birthdate ) AS
-- First employee will be 20 tomorrow
SELECT 1, ADD_MONTHS(TRUNC(SYSDATE), -20*12) + INTERVAL '1' DAY FROM DUAL UNION ALL
-- Second employee is 25 today
SELECT 2, ADD_MONTHS(TRUNC(SYSDATE), -25*12) FROM DUAL;
Outputs:
AGE
19
fiddle
You can subtract your MAX(birthdate) from SYSDATE - the result is number of days so you should convert days to years.
WITH
tbl AS
(
select
to_date('09-09-1965', 'dd-mm-yyyy') birthdate,
SYSDATE my_sysdate
from dual
)
SELECT FLOOR((my_sysdate - MAX(birthdate))/ 365) "YEARS_OLD" From tbl
YEARS_OLD
-----------
57
If you don't care much about months and days, a simple option is to extract year from sysdate and youngest birthdate and subtract them:
Sample data:
SQL> with employees (employeeid, lastname, birthdate) as
2 (select 1, 'Little', date '2015-08-25' from dual union all --> youngest
3 select 2, 'Foot' , date '2000-11-13' from dual
4 )
Query:
5 select extract(year from sysdate) - extract(year from max(birthdate)) as age
6 from employees;
AGE
----------
8
SQL>

Extract last modified date from backup snapshots in bigquery

I have snapshots backed up everyday and named in this format: TableName_20221218
I want to extract the date from the name of the snapshots to create a date column
Currently, i am manually adding date columns this way but it is kinda inconvenient because i have to update the code everyday
select id, date('2022-11-17') as date, rfm_r, rfm_f, rfm_m, recency_score, phone, recency_score_detail, gender, age_group, city from `backup.t1_customer_dependent_20221117`
union all
select id, date('2022-11-18') as date, rfm_r, rfm_f, rfm_m, recency_score, phone, recency_score_detail, gender, age_group, city from `backup.t1_customer_dependent_20221118`
union all
select id, date('2022-11-19') as date, rfm_r, rfm_f, rfm_m, recency_score, phone, recency_score_detail, gender, age_group, city from `backup.t1_customer_dependent_20221119`
union all
select id, date('2022-11-20') as date, rfm_r, rfm_f, rfm_m, recency_score, phone, recency_score_detail, gender, age_group, city from `backup.t1_customer_dependent_20221120`
Instead of that i want to automatically take the date from the name of the snapshot to create the date column and transform the code to some thing like this
select id, date, rfm_r, rfm_f, rfm_m, recency_score, phone, recency_score_detail, gender, age_group, city from `backup.t1_customer_dependent*`
Anyone know how to do this ?
Im new to bigquery so any help will be greatly appreciated
Thanks
Consider using _TABLE_SUFFIX for wildcard tables.
SELECT id, PARSE_DATE('%Y%m%d', _TABLE_SUFFIX) AS date, rfm_r ...
FROM `backup.t1_customer_dependent_*`

SQL min / max with all fields

I am facing a simple problem with an SQL query that I do not know how to tackle.
I have a table with the following structure
CITY COUNTRY DATES TEMPERATURE
Note that for a given country, I can have several cities. And, for a given city, I have several rows giving me the TEMPERATURE at each available DATE. This is just a time serie.
I would like to write a query which gives me for every cities the DATE where the TEMPERATURE is the MIN and the DATE where the TEMPERATURE is the MAX. The query should return something like that:
CITY COUNTRY DATE_MIN_TEMPERATURE MIN_TEMPERATURE DATE_MAX_TEMPERATURE MAX_TEMPERATURE
Any idea on how to achieve this?
Best regards,
Deny
Oracle provides keep/dense_rank first for this purpose:
select city,
min(temperature) as min_temperature,
max(date) keep (dense_rank first order by temperature asc) as min_temperature_date,
max(temperature) as max_temperature,
max(date) keep (dense_rank first order by temperature desc) as max_temperature_date
from t
group by city;
Note that this returns only one date if there are ties. If you want to handle that, more logic is needed:
select city, min(temperature) as min_temperature,
listagg(case when seqnum_min = 1 then date end, ',') within group (order by date) as mindates,
max(temperature) as max_temperature,
listagg(case when seqnum_max = 1 then date end, ',') within group (order by date) as maxdates,
from (select t.*,
rank() over (partition by city order by temperature) as seqnum_min,
rank() over (partition by city order by temperature desc) as seqnum_max
from t
) t
where seqnum_min = 1 or seqnum_max = 1
group by city;
In Oracle 11 and above, you can use PIVOT. In the solution below I use LISTAGG to show all the dates in case of ties. Another option is, in the case of ties, to show the most recent date when the extreme temperature was reached; if that is preferred, simply replace LISTAGG(dt, ....) (including the WITHIN GROUP clause) with MAX(dt). However, in that case the first solution offered by Gordon (using the first function) is more efficient anyway - no need for pivoting.
Note that I changed "date" to "dt" - DATE is a reserved word in Oracle. I also show the rows by country first, then city (the more logical ordering). I created test data in a WITH clause, but the solution is everything below the comment line.
with
inputs ( city, country, dt, temperature ) as (
select 'Palermo', 'Italy' , date '2014-02-13', 3 from dual union all
select 'Palermo', 'Italy' , date '2002-01-23', 3 from dual union all
select 'Palermo', 'Italy' , date '1998-07-22', 42 from dual union all
select 'Palermo', 'Italy' , date '1993-08-24', 30 from dual union all
select 'Maseru' , 'Lesotho', date '1994-01-11', 34 from dual union all
select 'Maseru' , 'Lesotho', date '2004-08-13', 12 from dual
)
-- >> end test data; solution (SQL query) begins with the next line
select country, city,
"'min'_DT" as date_min_temp, "'min'_TEMP" as min_temp,
"'max'_DT" as date_max_temp, "'max'_TEMP" as max_temp
from (
select city, country, dt, temperature,
case when temperature = min(temperature)
over (partition by city, country) then 'min'
when temperature = max(temperature)
over (partition by city, country) then 'max'
end as flag
from inputs
)
pivot ( listagg(to_char(dt, 'dd-MON-yyyy'), ', ')
within group (order by dt) as dt, min(temperature) as temp
for flag in ('min', 'max'))
order by country, city -- ORDER BY is optional
;
COUNTRY CITY DATE_MIN_TEMP MIN_TEMP DATE_MAX_TEMP MAX_TEMP
------- ------- ------------------------ ---------- -------------- ----------
Italy Palermo 23-JAN-2002, 13-FEB-2014 3 22-JUL-1998 42
Lesotho Maseru 13-AUG-2004 12 11-JAN-1994 34
2 rows selected.
Instead of keep/dense_rank first function you can also use FIRST_VALUE and LAST_VALUE:
select distinct city,
MIN(temperature) OVER (PARTITION BY city) as min_temperature,
FIRST_VALUE(date) OVER (PARTITION BY city ORDER BY temperature) AS min_temperature_date,
MAX(temperature) OVER (PARTITION BY city) as max_temperature,
LAST_VALUE(date) OVER (PARTITION BY city ORDER BY temperature) AS max_temperature_date
FROM t;

Error using the DATEDIFF syntax

I'm trying to find the age of employees from the SAMPLE database using this code:
SELECT
EMPNO,
FIRSTNME,
LASTNAME,
JOB,
BIRTHDATE,
DATEDIFF(HOUR,BIRTHDATE,GETDATE())/8766 AS AGE
FROM EMPLOYEE
WHERE JOB LIKE '%R';
but I keep getting the error :
"HOUR" is not valid in the context where it is used.. SQLCODE=-206,
SQLSTATE=42703
This is using IBM Data Studio 4.1.
Assuming you're using DB2, it doesn't support DATEDIFF or GETDATE(). Instead, just subtract the dates and use CURRENT DATE:
SELECT EMPNO, FIRSTNME, LASTNAME, JOB, BIRTHDATE,
(CURRENT DATE - BIRTHDATE)/365.25 AS AGE
FROM EMPLOYEE
WHERE JOB LIKE '%R'
In DB2, the results of subtracting two dates is a duration in the form `YYYYMMDD'
So for instance, today April 23, 2015 the following:
select current_date - '1972-02-24' as myage
from sysibm.sysdummy1
returns: 430128
Years = 43
Months = 1
Days = 28
So what you want is:
SELECT EMPNO, FIRSTNME, LASTNAME, JOB, BIRTHDATE,
int((CURRENT DATE - BIRTHDATE) / 10000) AS AGE
FROM EMPLOYEE
WHERE JOB LIKE '%R'

Find hire date difference between two employees

I have an employee table where the fields are:
first_name, last_name, hire_date, salary, department_id, department_name, and so on.
I intend to find the hire date difference between EMPLOYEE1 and EMPLOYEE2, then EMPLOYEE2 and EMPLOYEE3, and so on.
I have to write a query in sql to display the first name and hire date difference of employee
We can use DATEDIFF to calculate the date difference.
e.g
SELECT DATEDIFF(SELECT DATE_ADD(start_date,INTERVAL 1 DAY),end_date);
hope it will help you
also there is also way of using to_days function. click here for more detail
Since you've still not mentioned what RDBMS you are using i'll start with SQL-Server:
WITH x
AS (SELECT first_name,
last_name,
hire_date,
salary,
department_id,
department_name,
hireNum=Row_number()
OVER(
ORDER BY hire_date)
FROM dbo.employee)
SELECT DiffDays=Datediff(day, x.hire_date, x2.hire_date),
first_name,
last_name,
hire_date,
salary,
department_id,
department_name
FROM x
INNER JOIN x x2
ON x.hirenum = x2.hirenum + 1
To find the difference between dates in Microsoft SQL 2012 using days (substitute day with year, hour, etc.):
Select datediff(day, HireDate, EndDate)
From Employee1