SQL Sum two values within same query - mysql

Good Day,
I have a table that contains 3 columns. Date, Store, Straight_Sales. Each day a new record is created for each store with their previous day's sales.
What I am trying to do is generate a result set that has both current month to date sales for each location as well as the past year same MTD sales.
I can accomplish this by using two totally separate queries and result sets however I am trying to include these in the same query for reporting purposes.
Here are my two current queries that work just fine:
Last Year Month to Date:
SELECT SUM(summ_sales_daily.straight_sales), store_master.name
FROM
store_master
INNER JOIN summ_sales_daily ON store_master.unit = summ_sales_daily.store
WHERE YEAR(date)=YEAR(DATE_SUB(NOW(), INTERVAL 1 YEAR)) AND MONTH(date)=MONTH(NOW())
GROUP BY summ_sales_daily.store ORDER BY summ_sales_daily.store
Current Year Month to Date:
SELECT SUM(summ_sales_daily.straight_sales), store_master.name
FROM
store_master
INNER JOIN summ_sales_daily ON store_master.unit = summ_sales_daily.store
WHERE YEAR(date)=YEAR(NOW()) AND MONTH(date)=MONTH(NOW())
GROUP BY summ_sales_daily.store ORDER BY summ_sales_daily.store
I'd like these to return the current and previous years MTD in the same result along with the store name (hence the join)
Any help would be awesome!
Using MariaDB

You can either use conditional aggregation and move the different conditions into a case expression within the sum function:
SELECT
store_master.name
, SUM(CASE WHEN YEAR(date)=YEAR(DATE_SUB(NOW(), INTERVAL 1 YEAR)) THEN summ_sales_daily.straight_sales ELSE 0 END) last_year_sales
, SUM(CASE WHEN YEAR(date)=YEAR(NOW()) THEN summ_sales_daily.straight_sales ELSE 0 END) current_year_sales
FROM store_master
INNER JOIN summ_sales_daily ON store_master.unit = summ_sales_daily.store
WHERE MONTH(date)=MONTH(NOW())
GROUP BY summ_sales_daily.store
ORDER BY summ_sales_daily.store;
Or you can calculate the two different values in a couple of derived tables that you join with:
SELECT
store_master.name,
last_year.sales as previous_mtd,
current_year.sales as current_mtd
FROM store_master
LEFT JOIN (
SELECT store, SUM(straight_sales) sales
FROM summ_sales_daily
WHERE YEAR(date)=YEAR(DATE_SUB(NOW(), INTERVAL 1 YEAR)) AND MONTH(date)=MONTH(NOW())
GROUP BY store
) last_year ON store_master.unit = last_year.store
LEFT JOIN (
SELECT store, SUM(summ_sales_daily.straight_sales) sales
FROM summ_sales_daily
WHERE YEAR(date)=YEAR(NOW()) AND MONTH(date)=MONTH(NOW())
GROUP BY store
) current_year ON store_master.unit = current_year.store ;
Sample SQL Fiddle
The first solution would probably perform better.

Related

GROUP BY on 3 columns along with IFNULL() repeating month names in MySQL query

I am working on a query that is meant to show the number of enquiries each month in last year for a particular salesperson.
SELECT
MONTHNAME(c.datefield) AS month,
YEAR(c.datefield) AS year,
IFNULL((
SELECT COUNT(cc.customer_date)
FROM crm_customers
WHERE cc.customer_salesperson = 5 LIMIT 1
), 0) AS Enquiries
FROM calendar AS c
LEFT JOIN crm_customers AS cc ON c.datefield = DATE(cc.customer_date)
WHERE YEAR(c.datefield) = YEAR(CURRENT_DATE - INTERVAL 1 YEAR)
GROUP BY YEAR(c.datefield), MONTH(c.datefield), cc.customer_salesperson
But above query is repeating month names, not sure why?
Here is my crm_customers table:
I am joining above table with a calendar table containing one single column in date format.
How can I exclude those repeating month names?
EDIT
My calendar table:
If the calendar table is a single column table then i am only assuming that you don't run MySQL 8.0 so your query could be written as:
SELECT
MONTHNAME(`c`.`datefield`) AS `Monthname`,
YEAR(NOW())-1 AS `Year`,
IFNULL(`t`.`Enquiries`,0) AS `Enquiries`
FROM `calendar` `c`
LEFT JOIN (SELECT
MONTH(`cc`.`customer_date`) AS `Month`,
YEAR(`cc`.`customer_date`) AS `Year`,
COUNT(`cc`.`customer_id`) AS `Enquiries`
FROM `crm_customers` `cc`
WHERE YEAR(`cc`.`customer_date`) = YEAR(NOW())-1
AND `cc`.`customer_salesperson`=5
GROUP BY MONTH(`cc`.`customer_date`)) `t`
ON `t`.`Month`= MONTH(`c`.`datefield`)
GROUP BY MONTH(`c`.`datefield`);
You can check the example in SQLFiddle

How to find which year do values tend to increase in ? in SQL

Basically I have a table like this:
Table Time:
ID.......Date
1......08/26/2016
1......08/26/2016
2......05/29/2016
3......06/22/2016
4......08/26/2015
5......05/23/2015
5......05/23/2015
6......08/26/2014
7......04/26/2014
8......08/26/2013
9......03/26/2013
The query should return like this
Year........CountNum
2016........4
2015........3
To find out which year does its value tend to increase in. I notice that I want to display the years that have more values (number of row in this case) than the previous year.
What I've done so far
SELECT Year, count(*) as CountNum
FROM Time
GROUP BY Year
ORDER BY CountNum DESC;
I don't know how to get the year from date format. I tried year(Date) function, but I got Null data.
Please help!
It should works fine.
select year(date), count(*) as countNum
from time
group by year(date)
order by countNum
Join the grouped data to itself with 1 year offset:
select
a.*
from
(
select year(`Date`) as _year, count(*) as _n
from time group by 1
) a
left join
(
select year(`Date`) as _year, count(*) as _n
from time group by 1
) b
on a._year = b._year-1
where a._n > b._n
order by 1

MySQL left join structure not returning months with 0 orders

I have two tables:
shine_orders
LU_CALENDAR
For context:
LU_CALENDAR is essentially a table containing all possible dates in a range. It has a days column called Calendar_date with all datestamps such as 2000-01-01.
shine_orders contains my orders, with a dt column that has a datetime stamp such as "2011-06-15 10:54:09".
I'm trying to return a value for all months in a range, even if for a particular app_id in shine_orders there are no rows on some months. The latter is what I'm struggling with. I can't get it to return data where the result was 0.
SQL Statement so far:
SELECT DATE_FORMAT(dt, '%b %y') as dtstr, COUNT(*)
FROM shine_orders
LEFT JOIN LU_CALENDAR
ON Date(shine_orders.dt) = LU_CALENDAR.Calendar_Date
WHERE shine_orders.type = 'PayPal'
AND shine_orders.app_id = '5'
AND DATE_ADD(LU_CALENDAR.Calendar_Date, INTERVAL 2 YEAR) > NOW()
GROUP BY dtstr
ORDER BY DATE_FORMAT(dt, '%y%m') ASC
Example output:
Would anybody here have any ideas what I'm doing wrong?
First off, you appear to have all the months in your example output. But I understand that your question is that there are some months that are skipped because the example output is zero.
I think that a right join will be appropriate instead of a left join in this case, which should mean that every row in the field calendar_date gets shown. Also, since you are right joining onto the table LU_CALENDAR, you need to make sure you group by something in LU_CALENDAR; so for your first line try:
SELECT DATE_FORMAT(Calendar_Date, '%b %y') as dtstr, COUNT(*)
This seemed to do the trick:
SELECT DATE_FORMAT(LU_CALENDAR.Calendar_Date, '%b %y') as dtstr, IFNULL(COUNT(shine_orders.id),0) as COUNT
FROM shine_orders
RIGHT JOIN LU_CALENDAR
ON LU_CALENDAR.Calendar_Date = Date(shine_orders.dt)
AND shine_orders.app_id = '5'
WHERE LU_CALENDAR.Calendar_Date
BETWEEN DATE(DATE_SUB(NOW() , INTERVAL 2 year)) AND DATE(NOW())
GROUP BY DATE_FORMAT(LU_CALENDAR.Calendar_Date, '%y%m')
ORDER BY DATE_FORMAT(LU_CALENDAR.Calendar_Date, '%y%m') ASC

Is there a MySQL Statement for this or are multiple statements needed?

I have a table with MLSNumber, ListingContractDate, CloseDate.
I want to summarize the activity grouped my month starting with the current month and going back to January 2000.
I have this statement which summarizes the ListingContractDate by month.
SELECT COUNT(MLSNumber) AS NewListings, DATE_FORMAT(ListingContractDate,'%M %Y')
FROM Listings
WHERE Neighbourhood = 'Beachside'
AND ListingContractDate >= '2000-01-01'
GROUP BY YEAR(ListingContractDate), MONTH(ListingContractDate)
ORDER BY ListingContractDate DESC
The two problems with this statement are if there is nothing found in a specific month it skips that month, and I would need to return a 0 so no months are missing, and I am not sure how to get the same count on the CloseDate field or if I just have to run a 2nd query and match the two results up by month and year using PHP.
An exceptionally useful item to have is a "tally table" which simply consists on a set of integers. I used a script found HERE to generate such a table.
With that table I can now LEFT JOIN the time related data to it as shown below:
set #startdt := '2000-01-01';
SELECT COUNT(MLSNumber) AS NewListings, DATE_FORMAT(T.Mnth,'%M %Y')
FROM (
select
tally.id
, date_add( #startdt, INTERVAL (tally.id - 1) MONTH ) as Mnth
, date_add( #startdt, INTERVAL tally.id MONTH ) as NextMnth
from tally
where tally.id <= (
select period_diff(date_format(now(), '%Y%m'), date_format(#startdt, '%Y%m')) + 1
)
) t
LEFT JOIN Temp On Temp.ListingContractDate >= T.Mnth and Temp.ListingContractDate < T.NextMnth
GROUP BY YEAR(T.Mnth), MONTH(T.Mnth)
ORDER BY T.Mnth DESC
Logc,
define a stating date
calculate the number of months from that date until now (using
PERIOD_DIFF + 1)
choose that number of records from the tally table
create period start and end dates (tally.Mnth & tally.NextMnth)
LEFT JOIN the actual data to the tally table using
Temp.ListingContractDate >= T.Mnth and Temp.ListingContractDate < T.NextMnth
group and count the data
see this sqlfiddle`

Query with sum case group by

I am facing problem with following query:
SELECT sum(CASE WHEN status.new_reg_yn='n'
AND month(status.visit_date)-1 = 8
AND year(status.visit_date) = 2015 THEN 1 ELSE 0 END)
FROM customer_visit_status_tbl status,
customer_details_tbl cust
WHERE status.customer_id = cust.customer_id
AND cust.client_id=65
GROUP BY status.customer_id
The problem is that this query is returning results for customer with same id though I used group by. For example, in the month of September, if same customer visits 5 times it is returning count as 5 instead of 1 though I used group by.
It is really unclear what you want... Yes, distinct customers for a given time period, but then you are taking the month of the date visited -1 and looking for that equal to 8. Being that current month is 9 (September), Are you just looking for those based on activity the month prior to whatever the current is? So, for example, if Sept, 2015, you want totals for Aug, 2015. In Jan, 2016, you would want Dec, 2015? If that is the case, you can use the current date to subtract 1 month and get that as basis of the query. Then you can have your additional specific client (65 in this case).
My (subselect sqlvars) pre-creates variables applied for the query. It computes one month ago by subtracting 1 month from whatever the current date it. Then uses that as basis of the month representing whatever was the prior month, and similarly for that respective year.
Since this will in essence create a single row return, there is no Cartesian result and you can just run with your original other tables for final counts.
select
count( distinct s.customer_id ) as UniqueCustomers
from
( select #oneMonthAgo := DATE_ADD(CURRENT_DATE, INTERVAL -1 MONTH),
#finalMonth := MONTH( #oneMonthAgo ),
#finalYear := YEAR( #oneMonthAgo ) sqlvars,
customer_visit_status_tbl s
JOIN customer_details_tbl c
on s.customer_id = c.customer_id
AND c.client_id = 65
where
s.new_reg_yn='n'
Update Ans -
Select count(*)
from
( SELECT distinct status.customer_id
FROM customer_visit_status_tbl status
, customer_details_tbl cust
WHERE status.customer_id = cust.customer_id
AND cust.client_id = 65
and status.new_reg_yn = 'n'
AND month(status.visit_date)-1 = 8
AND year(status.visit_date) = 2015
) customer_visited