简体   繁体   中英

mysql nested query not working with an AND condition

I don't understand this: the two following queries are almost identical, the only bit that differs is the "and o.shop_id=1" part, yet they don't produce the expected results.

The first query:

select count(*) as count
from ek_order o        
where 1


and  
(
  select
  s.code
  from ek_order_status s
  inner join ek_order_has_order_status h on h.order_status_id=s.id
  where o.id=h.order_id

  order by h.date DESC
  limit 0,1

) in ('preparing_order')

Result of the query: 1

The second query:

select count(*) as count
from ek_order o        
where 1

and o.shop_id=1


and  
(
  select
  s.code
  from ek_order_status s
  inner join ek_order_has_order_status h on h.order_status_id=s.id
  where o.id=h.order_id

  order by h.date DESC
  limit 0,1

) in ('preparing_order')

Result of the query: 0 ( I expected 1! )

My schema structure looks like this:

ek_order:

  • id: pk
  • shop_id: nullable fk
  • ...other fields not relevant here

ek_order_has_order_status:

  • id: pk (I noticed it was not needed, but too late...)
  • order_id: fk
  • order_status_id: fk
  • date: datetime
  • ...other fields not relevant here

ek_order_status:

  • id: pk
  • code: str
  • ...other fields not relevant here

The data

The ek_order_has_order_status table has a row that looks like this:

  • id: 182
  • order_id: 283,
  • order_status_id: 7 (this is the 'preparing_order' code from ek_order_status )

and in the ek_order table we can find that shop_id is indeed 1:

  • id: 283
  • shop_id: 1

So what I don't understand is why the second query returns 0 instead of 1. I tested all bits of the query apart and they seem to work (I tested the inner query first, then the outer query, both with success), but then, adding the "and o.shop_id=1" part makes the complete query fail.

Does anybody know why? and/or have a fix. (I could resort to do two queries, but for the sake of improving my sql knowledge I would prefer to understand the bottom of this).

Ps: basically, I'm trying to get the number of orders containing the 'preparing_order' status as its final/latest status, knowing that an order can have multiple statuses.

In your second query:

SELECT COUNT(*) as count
FROM ek_order o        
WHERE 1
AND o.shop_id=1
...

you are taking a count of the entire ek_order table, and it therefore does not even make sense to speak of the shop_id value for a single record. I suspect that what you intend is if you find any record which has a shop_id value of 1, then this passes as a logical true. If so, then you can use EXISTS :

SELECT COUNT(*) as count
FROM ek_order o        
WHERE 1
AND EXISTS (SELECT 1 FROM ek_order WHERE shop_id=1)
AND ...

If this doesn't work, then another option would be to take the max value of shop_id :

SELECT COUNT(*) as count
FROM ek_order o        
WHERE 1
AND MAX(shop_id) = 1
AND ...

This would make sense if you are certain that this table only has a single record and you just want to inline its value alongside the count.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM