mysql sum from two databases - mysql

SELECT db1.table.listener,
db2.table.listener,
SEC_TO_TIME( SUM( TIME_TO_SEC( db2.table.time ) ) + ( TIME_TO_SEC( db1.table.time ) ) ),
count( db2.table.listener )
FROM table
INNER JOIN db2.table
ON db1.table.listener = db2.table.listener
WHERE db2.table.ldate = '19.02.2013'
AND db1.table.ldate = '19.02.2013'
GROUP BY db2.table.listener, db1.table.listener
I have two tables in two different databases with same columns (listener,time,ldate). I need to sum times and group by listener. This query gives multiple records, i need only "listener, total time, number of listens". How can i do this with one query?
Desired result;
| listeners (from both table, full join) | count of values (from both table) | sum of time (from both table) |

See following:
SELECT db1.table.listener,
SEC_TO_TIME( SUM( TIME_TO_SEC( db2.table.time ) ) +
( TIME_TO_SEC( db1.table.time ) ) ),
count( db1.table.listener )
FROM table
INNER JOIN db2.table
ON db1.table.listener = db2.table.listener
WHERE db1.table.ldate = '19.02.2013'
GROUP BY db1.table.listener

Related

MySQL Use of Having and Where Clause

Having difficulty returning the desired results.
Here is my query:
SELECT
DATABASE()AS INVOICES_Range_$0,
count(
DISTINCT invoice_lines.invoice_header_id
)AS 'Invoice Header Count',
sum(invoice_lines.accounting_total)AS 'Dollar_Value',
100 * COUNT(
DISTINCT invoice_lines.invoice_header_id
)/(
SELECT
COUNT(
DISTINCT invoice_lines.invoice_header_id
)
FROM
invoice_lines
WHERE
(
invoice_lines. STATUS NOT LIKE '%new%'
)
AND(
invoice_lines. STATUS NOT LIKE '%voided%'
)
)AS 'Percent of All Invoices',
COUNT(approvals.approvable_id)/ count(
DISTINCT invoice_lines.invoice_header_id
)AS 'AVG_APPROVALS'
FROM
invoice_lines
LEFT JOIN approvals ON invoice_lines.invoice_header_id = approvals.approvable_id
WHERE
(
invoice_lines.accounting_total = 0
)
AND(
invoice_lines. STATUS NOT LIKE '%new%'
)
AND(
invoice_lines. STATUS NOT LIKE '%voided%'
);
This query returns results where any invoice line has a value of $0.
For reference, we may have an invoice where one line is $0 but the other lines total $600.
I am wanting to only include in the above query where the total of all the invoice lines equal $0.
I've tried:
SELECT
DATABASE()AS INVOICES_Range_$0,
count(
DISTINCT invoice_lines.invoice_header_id
)AS 'Invoice Header Count',
sum(invoice_lines.accounting_total)AS 'Dollar_Value',
100 * COUNT(
DISTINCT invoice_lines.invoice_header_id
)/(
SELECT
COUNT(
DISTINCT invoice_lines.invoice_header_id
)
FROM
invoice_lines
WHERE
(
invoice_lines. STATUS NOT LIKE '%new%'
)
AND(
invoice_lines. STATUS NOT LIKE '%voided%'
)
)AS 'Percent of All Invoices',
COUNT(approvals.approvable_id)/ count(
DISTINCT invoice_lines.invoice_header_id
)AS 'AVG_APPROVALS'
FROM
invoice_lines
LEFT JOIN approvals ON invoice_lines.invoice_header_id = approvals.approvable_id
WHERE
(
invoice_lines. STATUS NOT LIKE '%new%'
)
AND(
invoice_lines. STATUS NOT LIKE '%voided%'
)
HAVING
SUM(
invoice_lines.accounting_total = 0
);
However, that returns the same results. Also, when modified to
HAVING (SUM(invoice_lines.accounting_total) < 500 )
It returns all invoices and the total amount.
Any assistance would be greatly appreciated, as I cannot determine the proper method for limiting my results to those invoice_header_id to only count those invoices where the sum of all lines is equal to 0.
HAVING
SUM(
invoice_lines.accounting_total = 0
);
probably wants to be
HAVING
SUM(
invoice_lines.accounting_total
) = 0
The solution was to evaluate in the WHERE clause using the 'Dollar Value' identified earlier in the query.
I changed the SUM(invoice_lines.accounting_total) as TOTAL
and then in the WHERE clause I added AND (TOTAL = 0);
Worked like a champ.

(Newbie) MySQL View

I'm new to SQL and probably going about this the wrong way but could you help?
I need to create a VIEW in MySQL but I can't figure out how to combine these two SQL statements, as VIEWs do not accept multiple SELECTS or Variables.
NB: the second statement works perfectly when replacing the #numberOfGames var with the correct number (manually calculated).
First statement - to return the total number of games for year:
SELECT COUNT( id ) INTO #numberOfGames FROM tblgames WHERE gdate LIKE '2014%';
Second statement - to create VIEW data:
SELECT
p.player AS player,
COUNT( c.gid ) AS gameCount,
SUM( c.cash ) AS cash,
ROUND( AVG( c.cash ), 2 ) AS avg,
SUM( ( CASE WHEN ( c.wotn > 0 ) THEN c.wotn ELSE 0 END ) ) AS wotn,
SUM( ( CASE WHEN ( c.cash > 0 ) THEN c.cash ELSE 0 END ) ) AS cashWon,
SUM( ( CASE WHEN ( c.cash < 0 ) THEN c.cash ELSE 0 END ) ) AS cashLost,
ROUND( AVG( ( CASE WHEN ( c.cash >= 0 ) THEN c.cash END ) ),2 ) AS avgWin,
ROUND( AVG( ( CASE WHEN ( c.cash < 0 ) THEN c.cash END ) ),2 ) AS avgLoss,
IF(
( ( COUNT( c.pid ) > ( #numberOfGames / 3 ) ) AND ( COUNT( c.pid ) > 2 ) ),
ROUND( ( ( AVG( c.cash ) * 10 ) + 200 ), 2 ),
ROUND( AVG( c.cash ), 2 )
) AS sortingPoints
FROM tblplayers p
LEFT JOIN tblcash c ON p.id = c.pid
LEFT JOIN tblgames g ON g.id = c.gid
WHERE c.cash IS NOT NULL AND g.gdate LIKE '2014%'
GROUP BY c.pid
ORDER BY sortingPoints DESC;
I'm using the #numberOfGames vars for a simple maths equation that checks it a player has played more than a third of the total games in the year.
I hope someone can help point me it the right direction.
You are missing the point of what a view does.
You can't save multiple statements in one view. It's like trying to save two tables in one table. It's not possible.
What you need to do is, run your first Select, exactly as you have it. Save it as a view. Then you can use that result set as if it were any other live table, and join it to other tables in subsequent Select statements.

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