开发者

Strange behavior with row count affected by SELECT clause with an INNER JOIN? (MySQL 5.1.52)

开发者 https://www.devze.com 2023-02-16 14:44 出处:网络
I\'ve run into a strange problem with one of my test cases that I can not explain. It boils down to a query that should return 1 row returning zero instead.

I've run into a strange problem with one of my test cases that I can not explain. It boils down to a query that should return 1 row returning zero instead.

This is the query that is failing.

SELECT roles.id FROM `roles` 
  INNER JOIN `accounts_roles` ON `roles`.id = `accounts_roles`.role_id 
  WHERE (`roles`.`id` = 9) 
    AND (`accounts_roles`.account_id = 6 ) LIMIT 1;

11:24:07  [SELECT - 0 row(s), 0.001 secs]  Empty result set fetched

And this is the part that I can't explain.

If I change roles.id to * I can see that there is data there.

SELECT * FROM `roles` 
  INNER JOIN `accounts_roles` ON `roles`.id = `accounts_roles`.role_id 
  WHERE (`roles`.`id` = 9) 
    AND (`accounts_roles`.account_id = 6 ) LIMIT 1;


id  name   authorizable_type  authorizable_id  created_at           updated_at  account_id  role_id  created_at           updated_at  
--  -----  -----------------  ---------------  -------------------  ----------  ----------  -------  -------------------  ----------  
9   owner  Couple             1                2010-11-30 11:13:31  (null)      6           9        2010-11-30 11:13:31  (null) 

Why would the columns that I'm selecting make any difference in the total rows returned?

These are the two tables in question:

describe roles;

COLUMN_NAME        COLUMN_TYPE  IS_NULLABLE  COLUMN_KEY  COLUMN_DEFAULT  EXTRA           
-----------------  -----------  -----------  ----------  --------------  --------------  
id                 int(11)      NO           PRI         (null)          auto_increment  
name               varchar(40)  YES                      (null)                          
authorizable_type  varchar(30)  YES                      (null)                          
authorizable_id    int(11)      YES          MUL         (null)                          
created_at         datetime     YES                      (null)                          
updated_at         datetime     YES                      (null)    


describe accounts_roles;

COLUMN_NAME  COLUMN_TYPE  IS_NULLABLE  COLUMN_KEY  COLUMN_DEFAULT  EXTRA  
-----------  -----------  -----------  ----------  --------------  -----  
account_id   int(11)      YES   开发者_开发知识库       MUL         (null)                 
role_id      int(11)      YES          MUL         (null)                 
created_at   datetime     YES                      (null)                 
updated_at   datetime     YES                      (null)   


I would shift the query to the following... Being that "Roles" primary key IS the ID column, that would NEVER be duplicated, so the limit of 1 is unnecessary. Additionally, I would shift your qualifier of account ID into the join clause.

SELECT 
      roles.id 
   FROM 
      roles
         INNER JOIN accounts_roles ar
            ON roles.id = ar.role_id
           AND ar.account_id = 6 ) 
   WHERE 
      roles.id = 9


I'll leave this question up in the off-chance that it saves someone else some time and sanity. Looks like it was a bug in the version of MySQL I was using.

Fails

$ mysql -v
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.1.52 Source distribution

Works fine

$ mysql -v
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.1.55 Source distribution

I should have ported this app to postgres years ago.

0

精彩评论

暂无评论...
验证码 换一张
取 消