Query to find accounts with specified months - sql

I Want to extract those account ids which are present in may and JUNE but not in JULY . I have data for 6 months
i have tried using CONDITION(AND/ NOT)
SELECT ACCOUNT_ID, DATA_MONTH
FROM DATA1
WHERE DATA_MONTH ='01-MAY-18' AND DATA_MONTH <> '01-JULY-18
GROUP BY DATA_MONTH
I am still getting account ids which where in JULY

You can put the conditions you need in a HAVING clause:
SELECT ACCOUNT_ID
FROM DATA1
GROUP BY ACCOUNT_ID
HAVING
SUM(CASE WHEN MONTH(DATA_MONTH) = 5 THEN 1 ELSE 0 END) > 0
AND
SUM(CASE WHEN MONTH(DATA_MONTH) = 6 THEN 1 ELSE 0 END) > 0
AND
SUM(CASE WHEN MONTH(DATA_MONTH) = 7 THEN 1 ELSE 0 END) = 0
I assume that in your rdbms there exists a function like MONTH() to extract the month from the date.
If you want to check the year also, you can do it in each condition, so you must change to:
CASE WHEN MONTH(DATA_MONTH) = 7 AND YEAR(DATA_MONTH) = 2018 THEN 1 ELSE 0

Using SQL Server's Month function gives you an understandable example of how to solve this.
SELECT ACCOUNT_ID
FROM DATA1
WHERE MONTH(DATA_MONTH) in (5,6) AND YEAR(DATA_MONTH) = 2018 AND MONTH(DATA_MONTH) NOT IN (7)
GROUP BY ACCOUNT_ID

Your date formats look like Oracle, so I will answer for that database.
The idea is to use conditional aggregation:
SELECT ACCOUNT_ID, DATA_MONTH
FROM DATA1
WHERE DATA_MONTH >= DATE '2018-05-01' AND
DATA_MONTH < DATE '2018-08-01'
GROUP BY ACCOUNT_ID
HAVING COUNT(DISTINCT DATA_MONTH) = 2 AND
MAX(DATA_MONTH) < DATE '2018-07-01';
This assumes that all your dates are on the first of the month.

SELECT ACCOUNT_ID, DATA_MONTH
FROM DATA1
WHERE MONTH(DATA_MONTH) =5 AND MONTH(DATA_MONTH) = 6
GROUP BY DATA_MONTH

SELECT ACCOUNT_ID, DATA_MONTH
FROM DATA1
WHERE MONTH(DATA_MONTH) BETWEEN 5 AND 6
GROUP BY Year(DATA_MONTH),month(DATA_MONTH)

Related

infuse a sum of the value in the another column with a different filter than the total count column

First here's a sample table.
enter image description here
Provider_name patient date status length
AF AGUIR00001 07/05/2018 3 30
AF ABBOT00001 07/05/2018 30
BB ADAMS00001 07/05/2018 3 30
BB ACEVE00001 07/06/2018 3 30
I have created a query that lets me count the total number of appointments versus the number of appointments with a certain status(eg checked out). I was able to create it and group it by provider.
select provider_name,
count(patient) total,
sum(case when status = 3 then 1 else 0 end) as Checkedout
from appointment
group by provider_name
Then I moved on to the next phase which was to get the total length of those appointments with checkedout status. I made this query but it does not break down into each provider.
select provider_name,
count(patient) total,
sum(case when status = 3 then 1 else 0 end) as Checkedout,
(select sum(length) from appointment where status = 3
and date between '06/01/2018' and '07/06/2018')
from appointment where date between '06/01/2018' and '07/06/2018'
group by provider_name
I need it so that the last column in the query is segregated per provider_name.
Thank you in advance for helping me out.
Actually, you were on the right way, try this:
select provider_name,
count(patient) total,
sum(case when status = 3 then 1 else 0 end) as Checkedout,
sum(case when status = 3 then length else 0 end) as len_status3
from appointment
where date between '2018-01-06' and '2018-06-07'
group by provider_name;
According to your last comment, you need a WITH ROLLUP modifier for GROUP BY as in the following :
select coalesce(provider_name,'Total') as provider_name,
count(patient) total,
sum(case when status = 3 then 1 else 0 end) as Checkedout,
sum(case when status = 3 then length else 0 end) as len_status3
from appointment
where date between '2018-01-06' and '2018-06-07'
group by provider_name with rollup;
SQL Fiddle Demo
you shoul do as for checkedoutout
select provider_name,
count(patient) total,
sum(case when status = 3 then 1 else 0 end) as Checkedout,
sum( case when status = 3 then length else 0 ) as total_length
from appointment where date between '06/01/2018' and '07/06/2018'
group by provider_name

Counts based on hour SQL

How can I get the count per hour?
select count_hr_1, count_hr_2, count_hr_3 from db.table where year=2018 and month=01 and day=02 and hour=01 OR hour=02 OR hour=03;
This SQL/Query is probably invalid but I want to get the counts of hour 1,2,3
If you are able to process the resultset as multiple rows instead of one, you could use GROUP BY:
select hour, count(*)
from db.table
where
year = 2018
and month = 1
and day = 2
and hour in (1, 2, 3)
group by hour
select sum(case when hour = 1 then 1 else 0 end) as count_hr_1,
sum(case when hour = 2 then 1 else 0 end) as count_hr_2,
sum(case when hour = 3 then 1 else 0 end) as count_hr_3
from db.table
where year = 2018
and month = 1
and day = 2
and hour in (1,2,3)

Select multiple COUNTs for every day

I got a table of Visitors.
Visitor has the following columns:
Id
StartTime (Date)
Purchased (bool)
Shipped (bool)
For each day within the last 7 days, I want to select 3 counts of the Visitors who have that day as StartTime:
The count of total visitors
The count of total visitors where Purchased = true
The count of total visitors where Shipped = true
Ideally the returned result would be:
Day Total TotalPurchased TotalShipped
1 100 67 42
2 82 61 27
etc...
I am used to .NET Linq so this has proved to be quite a challenge for me.
All I have come up with so far is the following:
SELECT COUNT(*) AS Total
FROM [dbo].[Visitors]
WHERE DAY([StartTime]) = DAY(GETDATE())
It selects the total of the current day just fine, however I feel pretty stuck right now so it'd be nice if someone could point me in the right direction.
For the last 7 days use the query proposed by Stanislav but with this WHERE clause
SELECT DAY([StartTime]) theDay,
COUNT(*) AS Tot,
SUM(CASE WHEN Purchased=true THEN 1 ELSE 0 END) as TotPurch,
SUM(CASE WHEN Shipped=true THEN 1 ELSE 0 END) as TotShip
FROM [dbo].[Visitors]
WHERE [StartTime] BETWEEN GETDATE()-7 AND GETDATE()
GROUP BY DAY([StartTime])
SELECT COUNT(*) AS Total,
SUM(CASE WHEN Purchased=true THEN 1 ELSE 0 END) as TotalPurchased,
SUM(CASE WHEN Shipped=true THEN 1 ELSE 0 END) as TotalShipped
FROM [dbo].[Visitors]
WHERE DAY([StartTime]) = DAY(GETDATE())
and add GROUP BY DAY([StartTime]) as jarlh mentioned
Here's a simple select that will give you the dataset you want
SELECT DATEDIFF(day,StartTime, getdate())+1 as [Day], -- Add 1 to display 1 to 7 instead of 0 to 6
COUNT(*) as Total,
SUM(CASE WHEN Purchased = 1 THEN 1 ELSE 0 END) as TotalPurchased,
SUM(CASE WHEN Shipped = 1 THEN 1 ELSE 0 END) AS TotalShipped
FROM Visitors
WHERE DATEDIFF(day,startTime,GETDATE()) < 6
GROUP BY DATEDIFF(day,startTime,GETDATE())
ORDER BY 1
This query will not take into consideration the time component of the date.

How to show different dates data (from the same table) as columns in Oracle

I'm sorry if the title wasn't too clear, but the following explanation will be more accurate.
I have the following view:
DATE USER CONDITION
20140101 1 A
20140101 2 B
20140101 3 C
20140108 1 C
20140108 3 B
20140108 2 C
What I need to do is present how many users where in all conditions this week and 7 days before today.
Output should be like this:
Condition Today Last_Week (Today-7)
A 0 1
B 1 1
C 2 1
How can I do this in Oracle? I will need to do this for 4 weeks so itll be Today-7,14-21.
I've tried this with group by but I get the "week2" as rows. Then I've tried something like Select conditions, (select count(users) from MyView where DATE='Today') FROM MyView(looking at something thats actually working) but it doesnt work for me.
Achieved this with a little modification of the accepted answer:
select condition,
count(case when to_date(xdate) = to_date(sysdate) then 1 end) to_day,
count(case when to_date(xdate) = to_date(sysdate-7) then 1 end) last_7_days
from my_table
group by condition
select condition, count(case when to_date(xdate) = to_date(sysdate) then 1 end) to_day,
count(case when to_date(xdate) < to_date(sysdate) then 1 end) last_7_days
from my_table
where to_date(xdate) >= to_date(sysdate) - 7
group by condition
select condition
, sum
( case
when date between trunc(sysdate) - 7 and trunc(sysdate) - 1
then 1
else 0
end
)
last_week
, sum
( case
when date between trunc(sysdate) and trunc(sysdate + 1)
then 1
else 0
end
)
this_week
from table
group
by condition
By using the conditional count (as a sum) and grouping on condition you can filter out all desired dates. Note that using trunc will cause to use the begin of the day.

select sum of values: grouped by sign

I have a simple SQL table of the following format:
date | value
============
2010-01-01 | -54
2010-01-02 | 134
2010-01-03 | 73
With the following two SQL queries I can select the sum of values and distinguish between the sum of positive values and the sum of negative values.
SELECT YEAR(date), SUM(value) FROM table WHERE value > 0 GROUP BY YEAR(date)
SELECT YEAR(date), SUM(value) FROM table WHERE value < 0 GROUP BY YEAR(date)
Is there a way to do this in a single SQL query?
Thanks in advance!
Not tested (don't know if the case can be put within a SUM instruction), but the CASE instruction could be of help:
SELECT
YEAR(date),
SUM(CASE WHEN value > 0 THEN value ELSE 0 END) as positives_sum,
SUM(CASE WHEN value < 0 THEN value ELSE 0 END) as negatives_sum
FROM
table
GROUP BY
YEAR(date)
Many databases have a SIGN() function
SELECT YEAR(date),
SUM(value)
FROM table
GROUP BY YEAR(date),
SIGN(value)