Oracle sql query sum data every month - sql

Let's say i have selected data from oktober until desember like this
i want to get sum of buying customer in every months (okt-des)
The result i want is like table below
i already know how to get last day of months but i don't have idea query in SQL to get result like i need

One way to do this - if you just need the data for those three months - is to use conditional aggregation:
select name,
sum(case when dt >= date '2017-10-01' and dt < date '2017-11-01'
then buying end) as oktober,
sum(case when dt >= date '2017-11-01' and dt < date '2017-12-01'
then buying end) as november,
sum(case when dt >= date '2017-12-01' and dt < date '2018-01-01'
then buying end) as desember
from YOUR_TABLE
where dt >= date '2017-10-01' and dt < date '2018-01-01'
group by name
;
Note that date is an Oracle keyword which should not be used as a column name; I changed it to dt. YOUR_TABLE should be your actual table name.

Try this
DESC TABLE_NAME
NAME VARCHAR2(20 BYTE)
BUYING NUMBER
BUYING_DATE DATE
select * from
(
select name,buying,RTRIM(to_char(buying_Date,'Month')) dd
from
TABLE_NAME
)
PIVOT
(
SUM(buying)
for dd IN ('October','November','December')
);

Related

Suggested way to do a 'parallel period' SQL statement

Let's say I want to get the profit between two dates. Then I can do something like this:
SELECT SUM(Profit)
FROM Sales
WHERE date BETWEEN '2014-01-01' AND '2014-02-01' AND <other_filters>
I would then like to compare it to a previous period offset by a fixed amount. It could be written something like this to get it in two rows:
SELECT SUM(Profit)
FROM Sales
WHERE date BETWEEN '2014-01-01' AND '2014-02-01' AND <other_filters>
UNION ALL
SELECT SUM(Profit)
FROM Sales
WHERE date BETWEEN '2014-01-01' - INTERVAL 1 YEAR AND '2014-02-01' - INTERVAL 1 YEAR AND <other_filters>
Is there a way to do this without a union? I am looking for something like this:
SELECT
SELECT SUM(Profit),
???
FROM Sales
WHERE date BETWEEN '2014-01-01' AND '2014-02-01' AND <other_filters>
I think the tricky part here is how to 'un-do' the where filter for the offseted-time calculation.
You can use conditional aggregation and OR the range checks in the WHERE clause (unless they are subsequent in which case you can combine them directly of course).
SELECT sum(CASE
WHEN date >= '2014-01-01'
AND date < '2014-02-02' THEN
profit
ELSE
0
END),
sum(CASE
WHEN date >= '2014-01-01' - INTERVAL 1 YEAR
AND date < '2014-02-02' - INTERVAL 1 YEAR THEN
profit
ELSE
0
END)
FROM sales
WHERE date >= '2014-01-01'
AND date < '2014-02-02'
OR date >= '2014-01-01' - INTERVAL 1 YEAR
AND date < '2014-02-02' - INTERVAL 1 YEAR;
Note: Prefer not to use BETWEEN here but check for a right half open range check. That way, if the precision of date changes, records on the end past midnight are still in the results.

How to get count of a column between a certain date range without changing the Where clause in SQL

I have a table that has account number, group category and date.
I have a query that does this
Select count(AccNum)
FROM Table
Where date BETWEEN '2020-02-01' AND '2020-03-31'
AND
group IN ('groupA','groupB')
Now is there any way for me to make it work like this
Select count(AccNum) Where date between 2020-02-01 AND '2020-02-31' AS CountFebuary, count(AccNum) Where date between 2020-03-01 AND '2020-02-31' AS CountMarch,
FROM Table
Where date BETWEEN '2020-02-01' AND '2020-03-31'
AND
group IN ('groupA','groupB')
I want to be able to get the total count of accounts for each month without writing a separate query for it. Is that possible?
You can do conditional aggregation:
select
sum(case when date >= '2020-02-01' and date < '2020-03-01' then 1 else 0 end) cnt_february,
sum(case when date >= '2020-03-01' and date < '2020-04-01' then 1 else 0 end) cnt_march
from mytable
where
date >= '2020-02-01' and date < '2020-04-01'
and group IN ('groupA','groupB')
Since you only want two months of data, then we can shorten the conditional expressions a little:
select
sum(case when date < '2020-03-01' then 1 else 0 end) cnt_february,
sum(case when date >= '2020-03-01' then 1 else 0 end) cnt_march
from mytable
where
date >= '2020-02-01' and date < '2020-04-01'
and group IN ('groupA','groupB')
If you are running MySQL, we can shorten some more:
select
sum(date < '2020-03-01') cnt_february,
sum(date >= '2020-03-01') cnt_march
from mytable
where
date >= '2020-02-01' and date < '2020-04-01'
and group IN ('groupA','groupB')
Side note: group is a reserved word in most databases, hence not a good choice for a column name.

Last day of existence in table

Is it possible to find a day the most recent day someone was in the table before they dropped out of it during a subsetted time range?
I have something like:
SELECT
id
, MAX(day) AS day
FROM table
WHERE
day >= '2018-01-01' AND day <= '2019-08-17'
AND day != '2019-08-18'
GROUP BY 1
I'm trying to just get everyone who was within the date range '2018-01-01' and '2019-08-17', but then wasn't in the table on '2019-08-18'
But, this still leads me to capture people who did have a day on '2019-08-18' in the original table, the new table just leaves that day out instead of finding people who truly didn't have a record in that day
Use a having clause:
SELECT id, MAX(day) AS day
FROM table
WHERE day >= '2018-01-01'
GROUP BY id
HAVING MAX(day) <= '2019-08-17';
Put all the conditions in the HAVING clause:
SELECT
id,
MAX(CASE WHEN day BETWEEN '2018-01-01' AND '2019-08-17' THEN day END) AS day
FROM table
GROUP BY id
HAVING
SUM(CASE WHEN day BETWEEN '2018-01-01' AND '2019-08-17' THEN 1 ELSE 0 END) > 0
AND
SUM(CASE WHEN day = '2019-08-18' THEN 1 ELSE 0 END) = 0

JOIN two SELECT statement results from two different tables

I am trying to create a code to join two statements each from different table and conditions, as follows:
the first statement:
select TO_CHAR(Entry_date, 'MON.YYYY') AS Months, count(Customer_id) "Count Customer"
from table1
where entry_date >= TO_DATE('01.01.1900', 'DD.MM.YYYY')
AND entry_date <= TO_DATE('31.12.2017', 'DD.MM.YYYY')
and Customer_status = 'Active'
group by TO_CHAR(entry_date,'MON.YYYY')
order by to_date(TO_CHAR(entry_date, 'MON.YYYY'),'MON.YYYY')
The second statement:
select count (order_id) "Order"
from table2
where leave_date >= TO_DATE('01.01.1900', 'DD.MM.YYYY')
AND leave_date <= TO_DATE('31.12.2017', 'DD.MM.YYYY')
group by TO_CHAR(leave_date,'MON.YYYY')
order by to_date(TO_CHAR(leave_date, 'MON.YYYY'),'MON.YYYY')
the result should look like this
Months Count Customer Order
Jan. 2017 15 0
Feb. 2017 1 8
Mar. 2017 30 10
The order should be dependent on the Months that were stated in the first statement.
Thanks for your help in advance.
I would write this as:
select yyyymm, sum(cust_count) as cust_count, sum(num_orders) as num_orders
from ((select to_char(entry_date, 'YYYY-MM') as yyyymm, count(*) as cust_count, 0 as num_orders
from table1
where entry_date >= date '1900-01-01' and
entry_date < date '2018-01-01' and
Customer_status = 'Active'
group by to_char(entry_date, 'YYYY-MM')
) union all
(select to_char(leave_date, 'YYYY-MM') as yyyymm, 0,
count(*) as num_orders
from table2
where leave_date >= date '1900-01-01' and
leave_date < date '2018-01-31'
group by to_char(leave_date, 'YYYY-MM')
)
) tt
group by yyyymm
order by yyyymm;
Notes on some changes:
The use of date rather than to_char() with date constants.
The use of the format "YYYY-MM", which orders correctly. (You don't have to use it but it recommended.)
The union all brings all the data together. In Oracle, you can also use a full outer join, but that requires more use of coalesce().

How to display result in two column form one column resource with different where

I try to count record which is on current date and pass date from date column
DATE
'2013-03-04 00:00:00'
'2013-02-04 00:00:00'
'2013-02-04 00:00:00'
if today is '2013-03-04 00:00:00'
the result should be
CURRENT_DATE = 1
PASS_DATE = 2
I Don't know how to query it form one resource but different where condition
1st - date >= '2013-03-04 00:00:00'
2nd - date < '2013-03-04 00:00:00'
PLEASE HELP
I suggest using two sub-queries within a SELECT clause
select
(select count(*) from MyDates where DateValue < getdate()) as PastDate,
(select count(*) from MyDates where DateValue >= getdate()) as CurrentDate
You can replace getDate() with a date parameter or a hard-coded value such as '2013-03-04' if you wish.
One way to do it is to query for all dates and place 1\0 according to your condition
then just query again from the table an sum the columns.
SELECT sum([CURRENT_DATE]), sum([PASS_DATE])
FROM
(
SELECT
ID,
case when myDate >= getDate() then 1 else 0 end as [CURRENT_DATE],
case when myDate < getDate() then 1 else 0 end as [PASS_DATE]
FROM mytable
) as SourcTbl
Here is a SQL Fiddle http://sqlfiddle.com/#!3/e9c19/8