Error GROUP BY Dates MysQL - mysql

I am trying to group by dates 2 different tables. However, something is going wrong as I am not able to group by dates.
I have 2 tables First "Budget" and Second "Sales Performance By Region"
The Idea is to show the Budget for all the months (12 months)
and each month we have data we will see the Sales for each specific month.
SELECT
BB.RG,
BB.YEAR,
DATE_FORMAT( BB.MONTH, '%M' ) AS `MONTH`,
SPR.Bookings,
SPR.`Bookings PY`,
SPR.Billing,
SPR.`Billing PY`,
SPR.`GP Amt`,
SPR.`GP Amt PY`,
SUM( BB.BUDGET ) AS BUDGET
FROM
BRANCH_BUDGET BB
LEFT JOIN Sales_Performance_Region SPR
ON BB.MONTH = SPR.MONTH
WHERE
BB.RG = 'FE'
AND SPR.RG = 'FE'
AND BB.YEAR = '2018'
GROUP BY
BB.MONTH
Above you can see the code. Instead of showing the 12 Months due to I only have data for 2 Months is showing January and February.
I hope the question makes sense. Can you guide me?

Whenever you invoke a GROUP BY after a WHERE statement or any other aggregate function inside a SELECT statement you will need to treat everything inside the select statement as an aggregate, otherwise you will face problems:
In your code:
SELECT `BRANCH_BUDGET`.`RG` ,
`BRANCH_BUDGET`.`YEAR` AS `YEAR` ,
`DATE_FORMAT( `BRANCH_BUDGET`.`MONTH` , '%M' ) AS `MONTH` ,
`Sales_Performance_Region`.`Bookings` ,
`Sales_Performance_Region`.`Bookings PY` ,
`Sales_Performance_Region`.`Billing` ,
`Sales_Performance_Region`.`Billing PY` ,
`Sales_Performance_Region`.`GP Amt` ,
`Sales_Performance_Region`.`GP Amt PY` ,
SUM( `BRANCH_BUDGET`.`BUDGET` ) AS `BUDGET`
FROM (
`BRANCH_BUDGET`
LEFT JOIN `Sales_Performance_Region` ON ( `BRANCH_BUDGET`.`MONTH` =
`Sales_Performance_Region`.`MONTH` )
)
WHERE `BRANCH_BUDGET`.`RG` = 'FE'
AND `Sales_Performance_Region`.`RG` = 'FE'
AND `BRANCH_BUDGET`.`YEAR` = '2018'
GROUP BY `BRANCH_BUDGET`.`MONTH`
You only group by BRANCH_BUDGET.MONTH, but do not group by any other column or perform an aggregate function on any other column (save BRANCH_BUDGET.BUDGET). Thus your output is faulty in that it only returns two months.

First thanks for the comments I want to post the result in case someone is interested.
The issue was: I didn't join the Region (RG) from both tables. So the result should look like the code below:
SELECT `BRANCH_BUDGET`.`RG` ,
`BRANCH_BUDGET`.`YEAR` AS `YEAR` ,
DATE_FORMAT( `BRANCH_BUDGET`.`MONTH` , '%M' ) AS `MONTH` ,
`Sales_Performance_Region`.`Bookings` ,
`Sales_Performance_Region`.`Bookings PY` ,
`Sales_Performance_Region`.`Billing` ,
`Sales_Performance_Region`.`Billing PY` ,
`Sales_Performance_Region`.`GP Amt` ,
`Sales_Performance_Region`.`GP Amt PY` ,
SUM( `BRANCH_BUDGET`.`BUDGET` ) AS `BUDGET`
FROM (
`BRANCH_BUDGET`
LEFT JOIN `Sales_Performance_Region`
ON ( `Sales_Performance_Region`.`MONTH` = `BRANCH_BUDGET`.`MONTH` )
AND ( `Sales_Performance_Region`.`RG` = `BRANCH_BUDGET`.`RG` )
)
WHERE `BRANCH_BUDGET`.`RG` = 'FE'
AND `BRANCH_BUDGET`.`YEAR` = '2018'
GROUP BY `BRANCH_BUDGET`.`MONTH`

Related

Query in MySQL that get values from two tables and put them in a specific order

I want to get values from this two tables and put them in a GridView in a specific way.
First table is estimated income and the second is actual income.
This is the estimated income table:
and this is the actual income:
I want to get values from two tables and display them in a GridView to look like this table:
The code that i stuck in is:
select t as which , SUM(Amount_income_table) as Actual,
SUM(estimated_amount) as Estimated
from ((select MONTHNAME(Date_income_table) as T,
select SUM(Amount_income_table) as Actual
FROM bacci.income_table WHERE year(Date_income_table)='2017' GROUP BY
monthname(date_income_table))
)union all
(SELECT SUM(estimated_amount) as Estimated
FROM bacci.estimated_income_table WHERE estimated_year='2017' GROUP BY
estimated_month) order by MONTHNAME(Date_income_table);
Assuming that bacci.estimated_income_table is guaranteed to contain rows for all twelve months we want to return, and assuming estimated_month column is integer value 1 thru 12, I'd do something like this:
EDIT
It appears that estimated_month is actually the month name January, February, ... so we derive the month number (1 thru 12) from that ...
SELECT d.y_ AS `year`
, d.mn_ AS `month`
, IFNULL(SUM(d.actual),0) AS `actual`
, IFNULL(SUM(d.estimated),0) AS `estimated`
FROM (
SELECT YEAR(it.date_income_table) AS `y_`
, MONTH(it.date_income_table) AS `m_`
, MONTHNAME(it.date_income_table) AS `mn_`
, SUM(it.amount_income_table) AS `actual`
, NULL AS `estimated`
FROM bacci.income_table it
WHERE it.date_income_table >= '2017-01-01'
AND it.date_income_table < '2017-01-01' + INTERVAL 1 YEAR
GROUP
BY YEAR(it.date_income_table)
, MONTH(it.date_income_table)
, MONTHNAME(it.date_income_table)
UNION ALL
SELECT ei.estimated_year AS `y_`
, MONTH(STR_TO_DATE(ei.estimated_month,'%M')) AS `m_`
, ei.estimated_month AS `mn_`
, NULL AS `actual`
, SUM(ei.estimated_amount) AS `estimated`
FROM bacci.estimated_income_table ei
WHERE ei.estimated_year = '2017'
GROUP
BY ei.estimated_year
, MONTH(STR_TO_DATE(ei.estimated_month,'%M'))
, ei.estimated_month
) d
GROUP
BY d.y_
, d.m_
, d.mn_
ORDER
BY d.y_
, d.m_

Subtracting Time using timediff

help. I have this query in mysql. What it does is combine fields from three tables. One field (Duration (h)) it subtracts the end time and start time. May time data is in the form of time only and not date time. So I decided to use timediff function. This runs well for time within the same day. But not time differences like 00:00 - 23:30; in this case I get the answer -23.5. What can I do to correct this. Thanks in advance.
SELECT `tblproductiondata`.`productionDay` , `tbllinestoppagecategories`.`category` , `tblshifts`.`ID` , `tblstoppagedescriptions`.`endTime` , `tblstoppagedescriptions`.`startTime` , IFNULL( ROUND( `tblstoppagedescriptions`.`duration(mins)` /60, 2 ) , ROUND( (
TIME_TO_SEC( TIMEDIFF( `tblstoppagedescriptions`.`endTime` , `tblstoppagedescriptions`.`startTime` ) ) /3600 ) , 2 )
) AS `Duration (h)`
FROM (
`tbllinestoppagecategories`
INNER JOIN `tblstoppagereasons` ON `tbllinestoppagecategories`.`categoryID` = `tblstoppagereasons`.`stoppagecategory`
)
INNER JOIN (
`tblshifts`
INNER JOIN (
`tblproductiondata`
INNER JOIN `tblstoppageDescriptions` ON `tblproductiondata`.`productionID` = `tblstoppagedescriptions`.`prodDate`
) ON `tblshifts`.`ID` = `tblproductiondata`.`shiftName`
) ON `tblstoppageReasons`.`resID` = `tblstoppagedescriptions`.`stoppageReason`
WHERE (
(
(
`tbllinestoppagecategories`.`category`
) <> "Changeover Maintenance Activities"
)
)
ORDER BY `tblproductiondata`.`productionDay` ASC
try
TIME_TO_SEC(
TIMEDIFF(
CONCAT(tblproductiondata.productionDay, ' ', tblstoppagedescriptions.endTime),
CONCAT(tblproductiondata.productionDay, ' ', `tblstoppagedescriptions`.`startTime`)
)
)

Mysql Self Join to find a parent child relationship in the same table

Im trying to calculate the amount of money won by all the offspring of a male race horse (Sire) over a time period. Listed by the Sire with the most amount of money won.
I run the query and get the result Im after with one problem, I cant display the sires name, only their ID.
SELECT `horses`.`SireID` AS `SireID` , `horses`.`HorseName` AS `Sire Name`,
COUNT( `runs`.`HorsesID` ) AS `Runs` ,
COUNT(
CASE WHEN `runs`.`Finish` =1
THEN 1
ELSE NULL
END ) AS `Wins` ,
CONCAT( FORMAT( (
COUNT(
CASE WHEN `runs`.`Finish` =1
THEN 1
ELSE NULL
END ) / COUNT
( `runs`.`TrainersID` ) ) *100, 0 ) , '%'
) AS `Percent` ,
FORMAT( SUM( `runs`.`StakeWon` ) , 0 ) AS `Stakes`
FROM runs
INNER JOIN horses ON runs.HorsesID = horses.HorsesID
INNER JOIN races ON runs.RacesID = races.RacesID
WHERE `races`.`RaceDate` >= STR_TO_DATE( '2012,07,01', '%Y,%m,%d' )
AND `races`.`RaceDate` < STR_TO_DATE( '2012,07,01', '%Y,%m,%d' ) + INTERVAL 1
MONTH
AND `horses`.`SireID` <> `horses`.`HorsesID`
GROUP BY `horses`.`SireID`, `horses`.`HorseName`
ORDER BY SUM( `runs`.`StakeWon` ) DESC
Take a record in the horse table for example, a horse has a horsesID and they also have a sireID (their father). The sireID has an equivalent horsesID in another record in the same table as it is also a horse
Basically I need to map the horseName to the sireID.
I thought a self join would work.
`AND `horses`.`SireID` <> `horses`.`HorsesID``
but it doesn't return the correct Sire name corresponding to the SireID.
You can do a JOIN on the table itself. Here's a simpler example:
SELECT Horses.HorseID, Horses.HorseName, Horses.SireID, b.HorseName as SireName
FROM Horses
LEFT JOIN Horses b ON (Horses.SireID = b.HorseID)
You can probably figure out how to add the conditions from here.
join horses sires on sires.HorsesID = horses.SireID

MySQL Join Two Queries Horizontally

I have a query that works correctly to pull a series of targets and total hours worked for company A. I would like to run the exact same query for company B and join them on a common date, which happens to be grouped by week. My current query:
SELECT * FROM (
SELECT org, date,
( SELECT SUM( target ) FROM target WHERE org = "companyA" ) AS companyA_target,
SUM( hours ) AS companyA_actual
FROM time_management_system
WHERE org = "companyA"
GROUP BY WEEK( date )
ORDER BY DATE
) q1
LEFT JOIN (
SELECT org, date,
( SELECT SUM( target ) FROM target WHERE org = "companyB" ) AS companyB_target,
SUM( hours ) AS companyB_actual
FROM time_management_system
WHERE org = "companyB"
GROUP BY WEEK( date )
ORDER BY DATE
) q2
ON q1.date = q2.date
The results show all of the dates / information of companyA, however companyB only shows sporadic data. Separately, the two queries will show the exact same set of dates, just with different information in the 'target' and 'actual' columns.
companyA 2012-01-28 105.00 39.00 NULL NULL NULL NULL
companyA 2012-02-05 105.00 15.00 NULL NULL NULL NULL
companyA 2012-02-13 105.00 60.50 companyB 2012-02-13 97.50 117.50
Any idea why I'm not getting all the information for companyB?
As a side note, would anybody be able to point in the direction of converting each row's week value into a column? With companyA and companyB as the only two rows?
I appreciate all the help! Thanks.
WITH no date apparent in the target table, the summation will be constant across all weeks. So, I have performed a pre-query for only those "org" values of company A and B with a group by. This will ensure only 1 record per "org" so you don't get a Cartesian result.
Then, I am querying the time_management_system ONCE for BOTH companies. Within the field computations, I am applying an IF() to test the company value and apply when correct. The WEEK activity is the same for both in the final result, so I don't have to do separately and join. This also prevents the need of having the date column appear twice. I also don't need to explicitly add the org column names as the final column names reflect that.
SELECT
WEEK( tms.date ) as GrpWeek,
IF( tms.org = "companyA", TargetSum.CompTarget, 00000.00 )) as CompanyATarget,
SUM( IF( tms.org = "companyA", tms.hours, 0000.00 )) as CompanyAHours,
IF( tms.org = "companyB", TargetSum.CompTarget, 00000.00 )) as CompanyBTarget,
SUM( IF( tms.org = "companyB", tms.hours, 000.00 )) as CompanyBHours
from
Time_Management_System tms
JOIN ( select
t.org,
SUM( t.target ) as CompTarget
from
Target T
where
t.org in ( "companyA", "companyB" )
group by
t.org ) as TargetSums
ON tms.org = TargetSums.org
where
tms.org in ( "companyA", "companyB" )
group by
WEEK( tms.date )
order by
WEEK( tms.date )
Both of your subqueries are wrong.
Either you want this:
SELECT
org,
WEEK(date),
( SELECT SUM( target ) FROM target WHERE org = "companyB" ) AS companyB_target,
SUM( hours ) AS companyB_actual
FROM time_management_system
WHERE org = "companyB"
GROUP BY WEEK( date )
Or else you want this:
SELECT
org,
date,
( SELECT SUM( target ) FROM target WHERE org = "companyB" ) AS companyB_target,
SUM( hours ) AS companyB_actual
FROM time_management_system
WHERE org = "companyB"
GROUP BY date
The way you are doing it now is not correctly formed SQL. In pretty much any other database your query would fail immediately with an error. MySQL is more lax and runs the query but gives indeterminate results.
GROUP BY and HAVING with Hidden Columns

How to merge the result of this 2 queries in mysql server

I am actually stuck in merging the result of this two queries:
first query:
SELECT c.code, c.name, pc.sku, pc.cat_code, pp.title
FROM `cat_parent` cp, cat c, prod_cat pc, products pp
WHERE c.code = cp.cat_code
AND cp.cat_code = pc.cat_code
AND pp.sku = pc.sku
AND cp.parent_code = 01110
AND hide =0
The result I get is:
Second query:
SELECT `sku` , `update_date` , `description` , count( * ) AS total_sold
FROM `orderline`
WHERE `update_date` >= ( DATE_ADD(CURDATE( ) , INTERVAL -14 DAY ) )
AND `update_date` <= ( DATE_ADD(CURDATE( ) , INTERVAL -7 DAY ) )
GROUP BY left( sku, 7 )
ORDER BY total_sold DESC
The result:
The question I want to ask that how can I get the result by filtering the sku available in both tables.
Just bit confused on that part....any ideas will be appreciated.
This is only part of the data. there is heaps of data. Yes, I want to merge the both tables and want to find the common sku available in both tables.
My expected result will be sku, title, total sold.
Thanks, anyway I managed to get around to get the result.
My final query:
SELECT * FROM (
SELECT sku , update_date , description FROM orderline WHERE
update_date >= '2012-03-06' AND update_date <= '2012-03-07' )g
JOIN (
SELECT c.code, c.name, pc.sku, pc.cat_code FROM cat_parent cp, cat
c, prod_cat pc, products pp WHERE c.code = cp.cat_code AND cp.cat_code
= pc.cat_code AND pp.sku = pc.sku AND cp.parent_code =01110 AND hide =0 )p ON left( g.sku, 7 ) = left( p.sku, 7 )
Something like this -
SELECT
`c`.`code`, `c`.`name`, `pc`.`sku`, `pc`.`cat_code`, `pp.title`,
`ol`.`sku`, `ol`.`update_date`, `ol`.`description`, COUNT(*) AS `total_sold`
FROM `cat_parent` `cp`
INNER JOIN `cat` `c`
ON `c`.`code` = `cp`.`cat_code`
INNER JOIN `prod_cat` `pc`
ON `cp`.`cat_code` = `pc`.`cat_code`
INNER JOIN `products` `pp`
ON `pp`.`sku` = `pc`.`sku`
INNER JOIN `orderline` `ol`
ON LEFT(`pc`.`sku`, 7) = LEFT(`ol`.`sku`, 7)
WHERE `cp`.`parent_code` = 01110
AND `hide` = 0
AND `ol`.`update_date` >= ( DATE_ADD(CURDATE( ) , INTERVAL -14 DAY ) )
AND `ol`.`update_date` <= ( DATE_ADD(CURDATE( ) , INTERVAL -7 DAY ) )
GROUP BY left( `ol`.`sku`, 7 )
ORDER BY `total_sold` DESC