user2538370
user2538370

Reputation:

Why doesn't my query return any rows

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

Answers (2)

ypercubeᵀᴹ
ypercubeᵀᴹ

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

Noam Rathaus
Noam Rathaus

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

Related Questions