Home > Blockchain >  Query not working how normal queries work
Query not working how normal queries work

Time:04-14

I have a query which is following:

select model_name, price 
from   `car` v
where ( select count(*) 
        from   `car` vc
        where  vc.`price` > v.`price`
      ) < 5

with a data set:

model_name  price
a            1
b            2
c            3
d            4
e            5
f            6
g            7
h            8
i            9
k            10

the upper query fetches the result as follows:

model_name  price
f            6
g            7
h            8
i            9
k            10

The main problem here is of understanding the logical flow behind this query. This logical flow which I understand was just like cross join the sub query will work on the back end like this:

VC_name     VC_Price    counts
a             1           0
b             2           1
c             3           2
d             4           3
e             5           4
f             6           5
g             7           6
h             8           7
i             9           8
k             10          9

If we take, back end calculation like this it should return counts which are less then 5, which has model_name a, b, c, d, e but instead this query outputs f, g, h, i, k.

Now if we proceed with how normal query works subquery would return only one record because of count, and after that if the condition is true it should return all rows and if false it should just return NULL. For example if subquery returns 4 then 4<5, true it should return all rows but the output is all different. The main question about this is how MYSQL is entertaining this query on backend, what would be the flow.

I hope I was able to explain my question.

Thanks in advance.

CodePudding user response:

the sub query will work on the back end like this:
...
where vc.price > v.price

Close, but the actual counts are reversed because your subquery is checking for cars with a greater price. Conceptually, it's doing this:

select v.model_name, v.price, count(*)-1
from   car v cross join car vc
where  vc.`price` >= v.`price`
group by v.model_name, v.price

Which produces these results:

model_name price count(*) **
a 1 9
b 2 8
c 3 7
d 4 6
e 5 5
f 6 4 Only 4 cars have price > 6
g 7 3 Only 3 cars have price > 7
h 8 2 Only 2 cars with price > 8
i 9 1 Only 1 cars with price > 9
k 10 0 No cars with price > 10

db<>fiddle here

Original query: ...

    where ( select count(*) 
            from   `car` vc
            where  vc.`price` > v.`price`
          ) < 5

So your query ends up returning the most expensive cars (f,g,h,i,k) because there are fewer cars with a greater price.

CodePudding user response:

Thank you for your response, Well I was asking for the flow of this Query. Studied some topics and just came to know the whole flow for this.

As SQL is a sequential language it will check the condition on every row, following query will perform like this:

On the fist step

select model_name, price 
from   `car` v
where ( select count(*) 
        from   `car` vc
        where  vc.`price` > v.`price` /* value for v.price = 1 and for vc.price
                                      it would iterate whole data from 1 to 10.
                                      So there will 9 values which are greater
                                      then 1. This is just working as loop. So 
                                      returned count(*) would be 9 which is 
                                      greater then 5, resulting in false 
                                      condition. So model_name 'a' will not be 
                                      returned in main select*/ 
      ) < 5

So this Query will iterate one by one for v.price, for every row of v.price it will iterate and check whole data of vc table. For example if v.price = 2 then there will 8 counts which are greater then 2. Until it reaches v.price = 10 then the count greater then 10 would be 0. In the end all those model_names which have counts less then 5 will be returned.

Once again Thankyou for your response.

  • Related