Reputation:
Structure table show here
If I use query:
select idn
from balans as outerB WHERE idn!='' group by idn order by
ifnull((select sum(innerB.amount) from balans as innerB
where innerB.idn = outerB.idn
and status='up'), 0) -
ifnull((select sum(innerB.amount) from balans as innerB
where innerB.idn = outerB.idn
and status='down'), 0) desc
limit 15
I get 2 rows.
But if I add condition >0
:
select idn from Balans as outerB WHERE idn!='' AND
(
(select sum(innerB.amount) from Balans as innerB
where innerB.idn = outerB.idn
and type='up') -
(select sum(innerB.amount) from Balans as innerB
where innerB.idn = outerB.idn
and type='down')
) > 0
group by idn order by
ifnull((select sum(innerB.amount) from Balans as innerB
where innerB.idn = outerB.idn
and type='up'), 0) -
ifnull((select sum(innerB.amount) from Balans as innerB
where innerB.idn = outerB.idn
and type='down'), 0) DESC
limit 15
In result I get 0 rows...
Tell me please where error? Why am I getting 0 rows?
Upvotes: 2
Views: 134
Reputation: 115530
You didn't include the IFNULL()
in the WHERE
condition. That is the reason you are getting 0 rows instead of 2. The Sums, returned by the subqueries, are NULL
(that's what SUM()
returns when there is no matching row, despite what one might think that 0
is more logical, it returns NULL
.)
And this added condition, I'd put it in HAVING
clause, not WHERE
(doesn't make a difference for the results in this case but it may be more efficient):
select idn from Balans as outerB WHERE idn !=''
group by idn
HAVING
ifnull((select sum(innerB.amount) from Balans as innerB
where innerB.idn = outerB.idn
and type='up'), 0) -
ifnull((select sum(innerB.amount) from Balans as innerB
where innerB.idn = outerB.idn
and type='down'), 0) > 0
order by
ifnull((select sum(innerB.amount) from Balans as innerB
where innerB.idn = outerB.idn
and type='up'), 0) -
ifnull((select sum(innerB.amount) from Balans as innerB
where innerB.idn = outerB.idn
and type='down'), 0) DESC
limit 15 ;
I don't see a reason to write this query with correlated subqueries. You can use derived tables and simple joins (also corrected the type
into status
):
SELECT di.idn
FROM
( SELECT idn
FROM Balans
GROUP BY idn
HAVING idn > ''
) AS di
LEFT JOIN
( SELECT idn, SUM(amount) AS up
FROM Balans
WHERE status = 'up'
GROUP BY idn
) AS bu
ON bu.idn = di.idn
LEFT JOIN
( SELECT idn, SUM(amount) AS down
FROM Balans
WHERE status = 'down'
GROUP BY idn
) AS bd
ON bd.idn = di.idn
WHERE COALESCE(bu.up, 0) - COALESCE(bd.down, 0) > 0 ;
Test at SQL-Fiddle
Upvotes: 1
Reputation: 5598
It is probably because
(select sum(innerB.amount) from Balans as innerB
where innerB.idn = outerB.idn
and type='up')
Isn't a number in all cases, making MySQL get confused.
As suggested, I would add IFNULL(..) to prevent MySQL thinking your are doing - on a non-number. Another option would be to do 0 + ... just before the (select sum...) that should also tell MySQL that we are talking about numbers here.
Upvotes: 0