SQL SUM Query with subqueries - mysql

I am trying to get the total 'capacity' for each station but I keep getting the error message "#1630 - FUNCTION tflBikes.COUNT does not exist":
SELECT Count(ts.capacity),
tbu.stationid,
ts.name,
ts.easting,
ts.northing,
tbu.t,
Round(Avg(availablebikes), 1) AS Average,
Round(Avg(availablebikes) / capacity * 100, 1) AS Percentage,
ts.postcode
FROM tflbikeusage tbu,
tflstations ts
WHERE tbu.stationid = ts.usageid
AND ts.easting = Abs(easting -
(SELECT easting
FROM tflstations
WHERE name = 'Hatton Garden, Holborn')) < 750 * 0.5
AND ts.northing = Abs(northing -
(SELECT northing
FROM tflstations
WHERE name = 'Hatton Garden, Holborn')) < 750 * 0.5
AND Hour(t) BETWEEN 10 AND 22
GROUP BY ts.capacity HAVING COUNT (ts.capacity) =
(SELECT Sum(capacityno)
FROM
(SELECT COUNT(ts.capacity) AS capacityNo,
tbu.stationid,
ts.name,
ts.easting,
ts.northing,
tbu.t,
Round(Avg(availablebikes), 1) AS Average,
Round(Avg(availablebikes) / capacity * 100 , 1) AS Percentage,
ts.postcode
FROM tflbikeusage tbu,
tflstations ts
WHERE tbu.stationid = ts.usageid
AND ts.easting = Abs(easting -
(SELECT easting
FROM tflstations
WHERE name = 'Hatton Garden, Holborn')) < 750 * 0.5
AND ts.northing = Abs(northing -
(SELECT northing
FROM tflstations
WHERE name = 'Hatton Garden, Holborn')) < 750 * 0.5
AND Hour(t) BETWEEN 10 AND 22
GROUP BY ts.capacity
ORDER BY percentage DESC)derivedTable)

You are aliasing tflbikesUsage to "tbu", so you should be using that going forward.

Related

mysql query takes too long

im working on a project and I created this sql query but it seems to be taking too long if I select a bigger date range, any idea how to make it faster, I tryed with union all and its much faster, but data is not the same, need help with code:
SELECT SUM(ROUND(total, 2)) as Enero from (
SELECT
FORMAT (
COALESCE(
CONCAT(ROUND(pro.precio / 1.14 , 2) + ROUND(p.recargo / 1.14 , 2) + (SELECT SUM(ROUND(precio / 1.14 , 2)) AS precio FROM acompanante_orden WHERE id_orden=p.id_orden) - p.descuento),
CONCAT(ROUND(pro.precio / 1.14 , 2) + ROUND(p.recargo / 1.14 , 2) - p.descuento)
)+ COALESCE(
ROUND(CONCAT(ROUND(pro.precio / 1.14 , 2) + (SELECT SUM(ROUND(precio / 1.14 , 2)) AS precio FROM acompanante_orden WHERE id_orden=p.id_orden) + ROUND(p.recargo / 1.14 , 2) - p.descuento) * 0.14, 2),
ROUND(CONCAT(ROUND(pro.precio / 1.14 , 2) + ROUND(p.recargo / 1.14 , 2) - p.descuento) * 0.14, 2)
), 2) as total
FROM orden p
LEFT JOIN producto_orden AS pro ON p.id_orden = pro.id_orden
LEFT JOIN acompanante_orden AS pa ON p.id_orden = pa.id_orden
WHERE p.actual_date BETWEEN '2017-04-01' AND '2017-04-01' and p.status=4
) sum_1
UNION ALL IDEA
select ROUND(( sum(precio)) * 1.14,2) as total from (
SELECT a.id_orden, ROUND(b.precio / 1.14 , 2) + ROUND(a.recargo / 1.14 , 2) - a.descuento as precio FROM orden a, producto_orden b WHERE a.id_orden=b.id_orden and a.actual_date BETWEEN '2017-04-01' AND '2017-04-01' and a.status=4 union all
SELECT c.id_orden, ROUND(d.precio / 1.14 , 2) as precio FROM orden c, acompanante_orden d WHERE c.id_orden=d.id_orden and c.actual_date BETWEEN '2017-04-01' AND '2017-04-01' and c.status=4
) sum_1
UPDATE:
SO here is my table schema: http://sqlfiddle.com/#!9/4fe12/2
WHAT I NEED:
I need to get TOTAL of monthly SELLS, but values on DB are with TAXES so before I get total I need to do some math:
DB INFO
PRODUCT= $50.00
ADDONS= $8.00
SHIPPING= $6.00
DISCOUNT= $2.00
RESULTS I NEED:
PRODUCT= $50.00 / 1.14 = $43.86
ADDONS= $8.00 / 1.14 = $7.02
SHIPPING= $6.00 / 1.14 =$5.26
SUBTOTAL= $56.14 - DISCOUNT($2)= $54.14
SUBTOTAL= $54.14 * 1.14 = $61.72
The first subquery is basically:
SELECT . . .
FROM orden p LEFT JOIN
producto_orden pro
ON p.id_orden = pro.id_orden LEFT JOIN
acompanante_orden pa
ON p.id_orden = pa.id_orden
WHERE p.actual_date BETWEEN '2017-04-01' AND '2017-04-01' and
p.status = 4
For this query, you want indexes on orden(status, actual_date, id_id_orden), producto_orden(id_orden), andacompanante_orden(id_orden)`.
I'm not sure what the rest of the query is.

mysql matching multiple and's and or's

I am trying to get rows from a table where there are matches on multiple other tables.
This is the query I am running.
SELECT qt.*, DATEDIFF(CURRENT_DATE, STR_TO_DATE(up.DOB, '%m-%d-%Y')) / 365 AS Age
FROM UserProfile AS up, Game AS g, QuestionTable AS qt
WHERE NOT EXISTS(SELECT * FROM Options WHERE UserID = 75 AND QID = qt.QID AND DateTime >= CURDATE())
AND g.Active = 1 AND g.QID = qt.QID
AND (((g.Gender = up.Gender OR g.Gender = 'B') AND ((g.City = up.City AND g.Zip = up.Zip AND g.Country = up.Country) OR g.Home = 0) AND ((Age BETWEEN g.Maximum AND g.Minimum) OR g.Age = 0) AND ((SQRT( POW( 69.1 * ( g.Latitude - -93.5746359 ) , 2 ) + POW( 69.1 * ( 44.9737707 - g.Longitude ) * COS( g.Latitude / 57.3 ) , 2 ) ) > g.Distance) OR g.Geo = 0)) OR g.Special = 0)
GROUP BY qt.QID
I have ran this expression through C# and it returns true, yet it is only matching on the 'g.Special = 0' part through MySql.
Any help on this would be much appreciated!
Resolved the issue by fixing some mistakes I made and changed the query to this,
SELECT *
FROM QuestionTable AS qt
WHERE NOT EXISTS
(SELECT * FROM Options WHERE UserID = 75 AND QID = qt.QID AND DateTime >= CURDATE())
AND EXISTS(SELECT g.* FROM UserProfile AS up, Game AS g WHERE g.Active = 1 AND g.QID = qt.QID AND(g.Special = 0 OR(
(g.Gender = up.Gender OR g.Gender = 'B') AND
((g.City = up.City AND g.zip = up.Zip AND g.Country = up.Country) OR g.Home = 0) AND
((SQRT( POW( 69.1 * ( g.Latitude - 44.9737707 ) , 2 ) + POW( 69.1 * ( -93.5746359 - g.Longitude ) * COS( g.Latitude / 57.3 ) , 2 ) ) < g.Distance) OR g.Geo = 0) AND
((DATEDIFF(CURRENT_DATE, STR_TO_DATE(DOB, '%m/%d/%Y'))/365.25 BETWEEN g.Minimum AND g.Maximum) OR g.Age = 0))))

Issue with Sum Calculation for multiple different IDs

The SQL code I have is shown below. The issue I am having is with calculating the sum of the Value of each Number. Doing them separately is okay and works when the Number is specified in the code but not when the number is not specified and I want the sum calculation to work for all separate Numbers.
{ Looks to calculate the value at the point of Tax. So all values before the tax date are ignored and all unit entries that occurred after the tax date are subtracted off the total units. The tax units are also subtracted off. The total units at point of tax, for each fund, is multiplied by the price at point of tax. The values of the funds are summed giving a total value for the number. }
This is the code I have done:
SELECT DISTINCT
A.Number,
CAST(ROUND((SELECT SUM(Val)
FROM (SELECT((S.TotalUnits -
(SELECT SUM(Units)
FROM TableIH AS F WHERE F.Fund = S.Fund AND F.Number = S.Number
AND F.Date >= (SELECT MIN(Date) FROM TableIH AS D
WHERE D.Fund= F.Fund AND D.Number = F.Number AND D.Entry = 'Tax' )
)
) * T.Price
) AS Val
FROM TableIH T
INNER JOIN TableID S
ON T.Number = S.Number
WHERE S.TotalUnits > 0 AND T.Fund = S.Fund
AND T.Price = ANY (SELECT (Price)
FROM TableIH AS E WHERE E.Entry = 'Tax' AND E.Number = T.Number)
)t
)
,2)
AS DECIMAL (25,2)) AS "Value"
FROM
TableIH A
INNER JOIN TableID C
ON C.Number = A.Number
group by A.Number
Tables are:
TableIH:
Number Fund Entry Units Price Date
12 YY RE 6 0.2 2015-02-02
12 YY Tax -10 0.1 2015-01-13
13 XX RE 6 0.2 2015-02-12
13 XX Tax -20 0.05 2014-12-11
13 MM Tax -25 0.6 2014-12-10
13 MM RE 8 0.2 2013-11-02
TableID
Number Fund TotalUnits
12 YY 2000
13 XX 1500
13 MM 500
DESIRED RESULT:
Number Value
12 [ ((2000) - (6) - (-10)) * 0.1 ] = 200.4
13 [ ((1500) - (6) - (-20)) * 0.05 ] + [ ((500) - (-25)) * 0.6 ] = 390.7
BUT GETTING: - Result is summing all instead of dividing it between each number.
Number Value
12 [ (200.4 + 390.7] = 591.1
13 [ (200.4 + 390.7] = 591.1
Any help with the errors would be greatly appreciated
Good evening, The problem is in your third nested subquery, you have no group on your sum, so it's summing all units, so you'll only get one total:
SELECT SUM(Units)
FROM TableIH AS F WHERE F.Fund = S.Fund AND F.Number = S.Number
AND F.Date >= (SELECT MIN(Date) FROM TableIH AS D
WHERE D.Fund= F.Fund AND D.Number = F.Number AND D.Entry = 'Tax'

Subtract all the rows from the value of first row in a MySQL column

This is my Select query
Select
snpc_stats.gamedetail.Player,
Sum(snpc_stats.gamedetail.Points + snpc_stats.gamedetail.Hits) As TotalPoints,
COUNT(*) As 'Games Played',
Sum(If(snpc_stats.gamedetail.Finish = 1, 1, 0)) As Wins,
Sum(If(snpc_stats.gamedetail.Finish = 2, 1, 0)) As Second,
Sum(If(snpc_stats.gamedetail.Finish = 3, 1, 0)) As Third,
Round(Avg(snpc_stats.gamedetail.Finish),2) As 'Average Finish',
Sum(snpc_stats.gamedetail.Hits) As `Total Hits`,
Sum(snpc_stats.gamedetail.ChampFund) As ChampFund,
Sum(snpc_stats.games.BuyIn) + (snpc_stats.gamedetail.ChampFund) As Cost,
Sum(snpc_stats.gamedetail.Winnings) As Winnings,
Sum(snpc_stats.gamedetail.Winnings) - (snpc_stats.games.BuyIn) - (snpc_stats.gamedetail.ChampFund) As 'Total Winnings',
COUNT(snpc_stats.games.Round) As round
From
snpc_stats.gamedetail Inner Join
snpc_stats.games On snpc_stats.games.GameID =
snpc_stats.gamedetail.GamesID
Where
snpc_stats.games.Season = '2015 Season'
Group By
snpc_stats.gamedetail.Player, snpc_stats.games.Season
Order By
TotalPoints Desc
After the TotalPoints Column I like to add a column that show the amount of points each player trails behind the leader, like the table below:
Rank | Player | Total Points | Points Behind
1 Bill 164 -
2 Al 152 -12
3 Ed 151 -13
4 Jill 123 -41
5 Bob 121 -43
6 Joe 102 -62
7 Dave 82 -82
8 Rob 60 -104
9 Doug 60 -104
10 Don 51 -113
11 Dan 30 -134
Any help would be so appreciated!
solution (1)If you are using a server side language that connects to the database and runs the query, you can preserve total points value of first row in some variable and subtracting all the following rows from it
solution (2)make a sub query that returns total points of the first row and use it in the selection part of the query
Select
snpc_stats.gamedetail.Player,
Sum(snpc_stats.gamedetail.Points + snpc_stats.gamedetail.Hits) As TotalPoints,
(Sum(snpc_stats.gamedetail.Points + snpc_stats.gamedetail.Hits) - (Select Sum(snpc_stats.gamedetail.Points + snpc_stats.gamedetail.Hits) From snpc_stats.gamedetail Inner Join snpc_stats.games On snpc_stats.games.GameID = snpc_stats.gamedetail.GamesID Where snpc_stats.games.Season = '2015 Season' Group By snpc_stats.gamedetail.Player, snpc_stats.games.Seaso Order By Sum(snpc_stats.gamedetail.Points + snpc_stats.gamedetail.Hits) Desc Limit 1)) As Points Behind,
COUNT(*) As 'Games Played',
Sum(If(snpc_stats.gamedetail.Finish = 1, 1, 0)) As Wins,
Sum(If(snpc_stats.gamedetail.Finish = 2, 1, 0)) As Second,
Sum(If(snpc_stats.gamedetail.Finish = 3, 1, 0)) As Third,
Round(Avg(snpc_stats.gamedetail.Finish),2) As 'Average Finish',
Sum(snpc_stats.gamedetail.Hits) As `Total Hits`,
Sum(snpc_stats.gamedetail.ChampFund) As ChampFund,
Sum(snpc_stats.games.BuyIn) + (snpc_stats.gamedetail.ChampFund) As Cost,
Sum(snpc_stats.gamedetail.Winnings) As Winnings,
Sum(snpc_stats.gamedetail.Winnings) - (snpc_stats.games.BuyIn) - (snpc_stats.gamedetail.ChampFund) As 'Total Winnings',
COUNT(snpc_stats.games.Round) As round
From
snpc_stats.gamedetail Inner Join
snpc_stats.games On snpc_stats.games.GameID =
snpc_stats.gamedetail.GamesID
Where
snpc_stats.games.Season = '2015 Season'
Group By
snpc_stats.gamedetail.Player, snpc_stats.games.Season
Order By
TotalPoints Desc

SUM from two tables, sort by country and publisher

I have two different sales tables and i want to SUM the quantity and FEEs for storeX and storeY from book_sales(isa), with quantity from all sales in the financial_report(xo). Im having trouble with both, and i dont know which JOIN i should use. The quantity calculation does not give any results and the fee calculation gives a number that is way to high. What is wrong here?
Please check my procedure if you have time:
ALTER PROCEDURE [dbo].[Report] #startDate VARCHAR(10),
#endDate VARCHAR(10)
AS
SELECT BB.name AS 'Publisher',
Sum(CASE
WHEN isa.report_source = 'storeX'
or isa.report_source = 'storeY' THEN
isa.quantity * xo.quantity
END) AS 'Total quantity',
Sum(CASE
WHEN isa.sales_price > 69
AND isa.report_source = 'storeX' THEN
6 * 1.25 * isa.quantity
WHEN isa.sales_price <= 69
AND isa.report_source = 'storeX' THEN
3 * 1.25 * isa.quantity
WHEN isa.sales_price <= 19
AND isa.report_source = 'storeX' THEN
1 * 1.25 * isa.quantity
WHEN isa.sales_price > 69
AND isa.report_source = 'storeY' THEN
6 * 1.25 * isa.quantity
WHEN isa.sales_price <= 69
AND isa.report_source = 'storeY' THEN
3 * 1.25 * isa.quantity
WHEN isa.sales_price <= 19
AND isa.report_source = 'storeY' THEN
1 * 1.25 * isa.quantity
WHEN xo.sales_price > 69
AND bb.country = 'NOR' THEN 6 * 1.25 * xo.quantity
WHEN xo.sales_price <= 69
AND bb.country = 'NOR' THEN 3 * 1.25 * xo.quantity
WHEN xo.sales_price > 69
AND bb.country <> 'NOR' THEN 6 * xo.quantity
WHEN xo.sales_price <= 69
AND bb.country <> 'NOR' THEN 3 * xo.quantity
END) AS 'Fee inc VAT(tot)'
FROM book_sales AS isa
INNER JOIN store AS BV
ON bv.store_id = isa.store_id
INNER JOIN financial_report AS xo
ON xo.identifiers = isa.identifiers
LEFT OUTER JOIN publisher AS BB
ON bb.publisher_id = bk.publisher_id
WHERE isa.sales_date >= CONVERT(DATETIME, #startDate, 20)
AND isa.sales_date < Dateadd(day, 1, ( CONVERT(DATETIME, #endDate, 20
) ))
GROUP BY bb.name,
bb.country
There are a few problems to sort out :
1- The total might be affected by NULL values, I suggest:
Sum(CASE
WHEN isa.report_source = 'storeX'
or isa.report_source = 'storeY' THEN
isnull(isa.quantity,0) * isnull(xo.quantity,0)
ELSE 0 END) AS 'Total quantity',
2- The case evaluation should be in order. For example:
WHEN isa.sales_price <= 69
AND isa.report_source = 'storeX' THEN
3 * 1.25 * isa.quantity
WHEN isa.sales_price <= 19
AND isa.report_source = 'storeX' THEN
1 * 1.25 * isa.quantity
<= 19 will never happen because it is also <= 69 and therefore the <=69 will evaluate true.
3- Cardinality between tables might be 1 to many so the values are summed multiple times when they shouldn't. You may need to select distinct or aggregate or flatten out some of the tables in the join to avoid this issue.