SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 21.01.2009 12:11:31

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

групповой IN

Подскажите, нет ли возможности в IN проверять по несколько полей?
Т.е.

Код:

WHERE 
 (f1,f2) IN ( (v1,v2), (v3,v4), (v5,v6) ... )

Вместо

Код:

WHERE 
 (f1 = v1 AND f2=v2)
OR 
 (f1 = v2 AND f2=v3)
OR 
 (f1 = v5 AND f2=v6)
...

Вроде по доке так нельзя, но может какой оператор подходящий вместо In  есть? Верхняя запись, имхо, выглядит гораздо компактней

Неактивен

 

#2 21.01.2009 12:18:32

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: групповой IN

Работает:


create table x (a int, b int);
insert into x values (1,2), (1,3), (4,7);
select * from x WHERE (a,b) IN ( (1,3), (4,8) );
 

+------+------+
| a    | b    |
+------+------+
|    1 |    3 |
+------+------+
1 row in set (0.01 sec)
 


Можно отправить как documentation bug на bugs.mysql.com

Неактивен

 

#3 21.01.2009 12:22:28

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

Re: групповой IN

Ёлки, надо было самому проверить.

А чего ж они в доке то про это ни слова не написали? smile
http://dev.mysql.com/doc/refman/5.1/en/ … unction_in

Неактивен

 

#4 21.01.2009 12:24:25

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: групповой IN

Правая рука не знает что делает левая. Надо баг документации им отправить.

Неактивен

 

#5 21.01.2009 17:50:24

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

Re: групповой IN

Хм. не подскажете почему в моей ситуации не работают индесы?

Таблица такая:

Код:

CREATE TABLE `se2` (
  `num` int(11) default NULL,
  `str` char(20) default NULL,
  `date` date default NULL,
  KEY `ix_num` (`str`,`num`,`date`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;

Записей примерно 4 млн, сочетание полей str+num+date практически уникально (~1% дублей)

Запрос

Код:

SELECT str,num FROM se2 WHERE str IN ('str1','str2','str3')

индекс использует.

Запрос

Код:

SELECT str,num FROM se2 WHERE (str,num) IN ('str1','num1')

тоже индекс использует.

А вот так:

Код:

SELECT str,num FROM se2 WHERE (str,num) IN (('str1','num1'),('str2','num2'),('str3','num3'))

не использует, хотя индекс "покрывающий". В чем может быть дело?

Explain выдает лаконично:

Код:

id    select_type    table    type    possible_keys    key    key_len    ref    rows    Extra
1    SIMPLE    se2    ALL                        4406921    Using where

Пробовал FORCE INDEX - не помогает. В какую сторону копнуть?

Неактивен

 

#6 21.01.2009 18:11:42

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: групповой IN

Боюсь, что копать надо в сторону bugs.mysql.com sad
Если переписать без туплов - использует ведь?

Неактивен

 

#7 22.01.2009 18:07:41

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

Re: групповой IN

Да, без туплов использует.
Может потому в доке и нет инфы про IN по нескольким столбцам до сих пор?

Неактивен

 

#8 22.01.2009 19:15:45

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: групповой IN

Не думаю. Это две независимые баги. Одна в документации, вторая - в оптимизаторе.

Неактивен

 

#9 23.01.2009 10:39:42

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

Re: групповой IN

Кстати, про "туплы в IN" в доке сказано, но в другом разделе - http://dev.mysql.com/doc/refman/5.1/en/ … tions.html

Код:

In other words, for a subquery that returns rows of n-tuples, this is supported:
(val_1, ..., val_n) IN (subquery)

И баг с индексами тоже известен еще с 2007 года, если я всё правильно понял - http://bugs.mysql.com/bug.php?id=31188

Неактивен

 

#10 23.01.2009 14:53:16

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: групповой IN

Ну, они его отнесли в feature request, а потому не обрабатывают. Похоже таки прийдется переписывать
без туплов запрос. Благо это не очень сложно.

Неактивен

 

#11 24.01.2009 02:06:58

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

Re: групповой IN

Придется. А в 5.1/6.0 всё так же? Просто у меня 5.0 и нет возможности проверить, а то может пификсили втихую...

Неактивен

 

#12 24.01.2009 15:56:28

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: групповой IN

Версия 5.1.21-beta-community


explain select str,num from se2 where (str,num) in (('str1','1'),('str2','2'));
 

Код:

id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra
1, 'SIMPLE', 'se2', 'index', '', 'ix_num', '30', '', 3, 'Using where; Using index'

Однако.


select str,num from se2 where (str,num) in ('str1','1');
ErrorNr 1241  Operand should contain 2 column(s)


select str,num from se2 where (str,num) in (('str1','1'));
ErrorNr 1267  Illegal mix of collations (cp1251_general_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '='
 
Что означает последняя ошибка?

Неактивен

 

#13 24.01.2009 22:36:50

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

Re: групповой IN

Могу только предположить, что mysql просекает, что одно поле число и сравнивает его в кодировке по умолчанию, а второе поле - строка, и сравнивает его в кодировке клиента. Так как они не совпадают - возникает ошибка. Наверно если такой запрос сделать из родного клиента mysql - ошибки не будет, а вы наверно сделали его из под винды в каком-нибудь query browser с кодировкой по умолчанию cp1251. Ну это только предположение.

Первая ошибка тоже интересна smile

Кстати где нибудь есть справочник под кодам ошибок и нотайсов с их описанием?

Неактивен

 

#14 24.01.2009 22:45:13

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: групповой IN

Ошибка возникает и в линуксе в консольном клиенте в koi8r (версия 5.0.45). Вот лог:

SET NAMES koi8r;
CREATE TABLE `se2` (   `num` int(11) default NULL,   `str` char(20) default NULL,   `date` date default NULL,   KEY `ix_num` (`str`,`num`,`date`) ) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
SELECT str,num FROM se2 WHERE (str,num) IN (('str1',1));

ERROR 1267 (HY000): Illegal mix of collations (cp1251_general_ci,IMPLICIT) and (koi8r_general_ci,COERCIBLE) for operation '='

Если сделать "SET NAMES cp1251", то ошибка исчезает, но это неправильно. Наверное тоже бага, что в туплях должны быть объекты с одинаковым collation

Неактивен

 

#15 24.01.2009 23:49:12

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

Re: групповой IN

rgbeast написал:


SELECT str,num FROM se2 WHERE (str,num) IN (('str1',1));

                                             ^^^^^^^^^

А так и вовсе нельзя, в доке про это прямо сказано:

You should never mix quoted and unquoted values in an IN list because the comparison rules for quoted values (such as strings) and unquoted values (such as numbers) differ. Mixing types may therefore lead to inconsistent results.

Неактивен

 

#16 24.01.2009 23:56:55

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: групповой IN

Меня смущает, что ошибка проявляется в запросе

SELECT str,num FROM se2 WHERE (str,num) IN (('str1','1'));

но отсутствует в запросе
SELECT str,num FROM se2 WHERE (str,num) IN (('str1','1'),('str2','2'));

Логики я здесь не улавливаю.

Неактивен

 

#17 25.01.2009 00:45:19

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: групповой IN

Если поставить кавычки, ничего не меняется - та же ошибка.

В запросе

SELECT str,num FROM se2 WHERE (str,num) IN (('str1','1'),('str2','2'));

действительно ошибки нет.

Неактивен

 

#18 25.01.2009 04:09:20

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

Re: групповой IN

Странно, но у меня не воспроизводится. Специально проапгрейдил реплику до 5.1.30-community-log. Картина такая же как на пятерке, а таких ошибок как у вас - нету ни там, ни там. Сервер на Win Server 2003 R2.

Более того, даже если убрать кавычки с числа - тоже ошибок нет. Но у меня кодировка на сервере по умолчанию cp1251 у клиента тоже, наверно поэтому?

Неактивен

 

#19 25.01.2009 12:07:10

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: групповой IN

Если кодировка клиента и таблицы совпадает - ошибки нет. Попробуй создать таблицу в кодировке KOI8R.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson