SELECT all at once - sql

I want to select patient_id and date difference from below table:
p_id TreatmentDate
15 2008-05-01
15 2008-05-03
15 2008-05-05
15 2008-05-07
16 2008-05-01
16 2008-05-03
16 2008-05-05
16 2008-05-09
16 2008-05-11
17 2008-05-03
17 2008-05-05
17 2008-05-07
I want to have this result:
p_id Day Difference
15 6 Days
16 10 Days
17 4 Days
Do you have any offer that can generate this result in sql statement?

This should work in general
select p_id, max(TreatmentDate) - min(TreatmentDate) from
patientsTable group by p_id
more specifically, for MSSQL Server
select p_id, DATEDIFF(D, MIN(TreatmentDate), MAX(TreatmentDate)) from
patientsTable group by p_id

MS SQL Server:
SELECT
p_id,
STR(DATEDIFF(DAY, MIN(TreatmentDate), MAX(TreatmentDate))) + ' Days' AS DayDifference
FROM
table
GROUP BY
p_id

MS SQL:
select
p_id,
datediff(d, min(TreatmentDate), max(TreatmentDate)) AS DayDifference
from
patientsTable
group by
p_id;

This will work:
SELECT p_id, CONCAT(max(TreatmentDate) - min(TreatmentDate),' Days') as "Day Difference"
FROM
patient_info
GROUP BY p_id;
Given this schema/data:
CREATE TABLE patient_info (
p_id INT,
TreatmentDate DATE
);
INSERT INTO patient_info
VALUES
(15,'2008-05-01'),
(15,'2008-05-03'),
(15,'2008-05-05'),
(15,'2008-05-07'),
(16,'2008-05-01'),
(16,'2008-05-03'),
(16,'2008-05-05'),
(16,'2008-05-09'),
(17,'2008-05-03'),
(17,'2008-05-05'),
(17,'2008-05-07');
+------+----------------+
| p_id | Day Difference |
+------+----------------+
| 15 | 6 Days |
| 16 | 8 Days |
| 17 | 4 Days |
+------+----------------+
3 rows in set (0.00 sec)
Please let me know if you need more help.

Related

Fetching Date and year from Timestamp column (Athena)

I'm working in Athena (SQL) and trying to extract the date, year and month from column called "createddate" which involves timestamp and its a varchar data type. I have tried bunch of queries but I am getting errors after errors. Can you please help me extracting the date, year, month, week from this createddate column?
The field "createddate" is found in the following format:
id
createddate
1
11/29/2016 10:58:02
2
12/04/2016 07:07:58
3
10/22/2018 03:47:23
4
10/22/2018 08:20:25
5
10/22/2018 08:29:26
6
10/22/2018 08:42:28
7
10/22/2018 08:46:21
8
10/22/2018 10:18:57
12
10/22/2018 22:16:46
13
10/22/2018 22:24:33
14
10/23/2018 02:55:49
15
10/23/2018 07:49:39
16
10/23/2018 09:15:57
32
10/26/2018 06:19:13
33
10/26/2018 06:21:09
34
10/26/2018 06:24:59
48
10/30/2018 19:11:41
49
10/30/2018 20:10:10
64
11/01/2018 18:06:15
65
11/01/2018 18:08:00
66
11/01/2018 18:08:37
2
12/04/2016 07:07:58
99
11/09/2018 23:52:02
100
11/09/2018 23:57:13
Here are all my attempts:
select * from table where YEAR(from_iso8601_timestamp(createddate)) = 2022
and MONTH(from_iso8601_timestamp(createddate)) = 6 limit 10
select date_format(createddate,'%m/%d/%Y %H:%m:%s') from table limit 10
select date_format(createddate,'%m/%d/%Y H:m:s') from table limit 10
select date_format(createddate,'%m/%d/%Y %H:%i:%s') from table limit 10
select date_parse(createddate, '%m/%d/%Y %H:%i%p') from table limit 10
select date_parse(createddate, ' %m/%d/%Y') from table limit 10
select cast(date_parse(createddate,'%Y-%m-%d %h24:%i:%s') as date) from table limit 10
Select CAST(date_format(date_parse(cast(createddate as varchar(10)), '%m%d%Y'), '%m/%d/%Y') AS DATE) from table limit 10
Try with this one:
WITH cte AS (
SELECT id,
DATE_PARSE(createddate, '%m/%d/%Y %H:%i:%s') AS createddate
FROM table
)
SELECT id,
createddate,
YEAR(createddate),
MONTH(createddate),
WEEK(createddate)
FROM cte
You can find the documentation relative to the employed date functions here.

SQL: Select only users who are new in 2021

If we have a table as follows:
User_ID
Order_date
Order_ID
1
2020-02-02
23
2
2021-03-03
45
1
2021-02-02
13
3
2019-05-23
34
3
2021-01-31
56
How to select only the user whose first order is in the year 2021 (in this case, only User 2)?
You can use aggregation:
select user_id
from t
group by user_id
having min(order_date) >= '2021-01-01';
This checks that the earliest order date is after the first of the year.

SQL sum and previous row [duplicate]

This question already has answers here:
Calculate a Running Total in SQL Server
(15 answers)
Closed 3 years ago.
I have the following table:
________________________
date | amount
________________________
01-01-2019 | 10
01-01-2019 | 10
01-01-2019 | 10
01-01-2019 | 10
02-01-2019 | 5
02-01-2019 | 5
02-01-2019 | 5
02-01-2019 | 5
03-01-2019 | 20
03-01-2019 | 20
These are mutation values by date. I would like my query to return the summed amount by date. So for 02-01-2019 I need 40 ( 4 times 10) + 20 ( 4 times 5). For 03-01-2019 I would need ( 4 times 10) + 20 ( 4 times 5) + 40 ( 2 times 20) and so on. Is this possible in one query? How do I achieve this?
My current query to get the individual mutations:
Select s.date,
Sum(s.amount) As Sum_amount
From dbo.Financieel As s
Group By s.date
You can try below -
DEMO
select dateval,
SUM(amt) OVER(ORDER BY dateval ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as amt
from
(
SELECT
dateval,
SUM(amount) amt
FROM t2 group by dateval
)A
OUTPUT:
dateval amt
01/01/2019 00:00:00 40
01/02/2019 00:00:00 60
01/03/2019 00:00:00 100
Try this below script to get your desired output-
SELECT A.date,
(SELECT SUM(amount) FROM <your_table> WHERE Date <= A.Date) C_Total
FROM <your_table> A
GROUP BY date
ORDER BY date
Output is-
date C_Total
01-01-2019 40
02-01-2019 60
03-01-2019 100
I suggest to use a window function, like this:
select date, sum(amount) over( order by date)
from table

Postgres count number or rows and group them by timestamp

Let's assume I have one table in postgres with just 2 columns:
ID which is PK for the table (bigint)
time which is type of timestamp
Is there any way how to get IDs grouped by time BY YEAR- when the time is date 18 February 2005 it would fit in 2005 group (so result would be)
year number of rows
1998 2
2005 5
AND if the number of result rows is smaller than some number (for example 3) SQL will return the result by month
Something like
month number of rows
(February 2018) 5
(March 2018) 2
Is that possible some nice way in postgres SQL?
You can do it using window functions (as always).
I use this table:
TABLE times;
id | t
----+-------------------------------
1 | 2018-03-14 20:04:39.81298+01
2 | 2018-03-14 20:04:42.92462+01
3 | 2018-03-14 20:04:45.774615+01
4 | 2018-03-14 20:04:48.877038+01
5 | 2017-03-14 20:05:08.94096+01
6 | 2017-03-14 20:05:16.123736+01
7 | 2017-03-14 20:05:19.91982+01
8 | 2017-01-14 20:05:32.249175+01
9 | 2017-01-14 20:05:35.793645+01
10 | 2017-01-14 20:05:39.991486+01
11 | 2016-11-14 20:05:47.951472+01
12 | 2016-11-14 20:05:52.941504+01
13 | 2016-10-14 21:05:52.941504+02
(13 rows)
First, group by month (subquery per_month).
Then add the sum per year with a window function (subquery with_year).
Finally, use CASE to decide which one you will output and remove duplicates with DISTINCT.
SELECT DISTINCT
CASE WHEN yc > 5
THEN mc
ELSE yc
END AS count,
CASE WHEN yc > 5
THEN to_char(t, 'YYYY-MM')
ELSE to_char(t, 'YYYY')
END AS period
FROM (SELECT
mc,
sum(mc) OVER (PARTITION BY date_trunc('year', t)) AS yc,
t
FROM (SELECT
count(*) AS mc,
date_trunc('month', t) AS t
FROM times
GROUP BY date_trunc('month', t)
) per_month
) with_year
ORDER BY 2;
count | period
-------+---------
3 | 2016
3 | 2017-01
3 | 2017-03
4 | 2018
(4 rows)
Just count years. If it's at least 3, then you group by years, else by months:
select
case (select count(distinct extract(year from time)) from mytable) >= 3 then
to_char(time, 'yyyy')
else
to_char(time, 'yyyy-mm')
end as season,
count(*)
from mytable
group by season
order by season;
(Unlike many other DBMS, PostgreSQL allows to use alias names in the GROUP BY clause.)

Oracle SQL - Creating Multiple Ranges for Date Possibilities in a Query

I have this query:
Select *
From Player_Chkin_Cs
That spits out the result:
Player_ID CS_ID CS_LISTING_ID CS_COMP_NAME PT_ADD CREATE_DTIME UUID
179364 300 60132 Wilshire 3 22-DEC-10 (null)
179364 320 68968 Wilshire 30 28-JAN-10 (null)
132489 200 55168 Wilshire 13 03-Jan-10 (null)
132489 900 65478 Wilshire 23 15-Feb-10 (null)
I want to create a query that returns the player_ids of only players who have create_dtimes that fall in both the ranges of 01-Dec-10 to 31-Dec-10 AND 01-Jan-10 to 31-Jan-10.(aka only Player_ID 179364 would show up in the results of this example)
Please let me know if you have any suggestions!
One option would be
SELECT player_id,
COUNT(DISTINCT trunc(create_dtime, 'MM')) num_months
FROM player_chkin_cs
WHERE trunc(create_dtime,'MM') IN (date '2010-12-01', date '2010-01-01')
GROUP BY player_id
HAVING COUNT(DISTINCT trunc(create_dtime, 'MM')) = 2