2013-12-18 2 views
3

Вот сценарий - У меня есть таблицаSQL SELECT ... В результате того,

CREATE TABLE IF NOT EXISTS `stylemaps` (
`zyid` varchar(9) CHARACTER SET ascii COLLATE ascii_bin NOT NULL, 
`styid` varchar(9) CHARACTER SET ascii COLLATE ascii_bin NOT NULL DEFAULT 'zzzz0000Z', 
UNIQUE KEY `zyid` (`zyid`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

Типичный набор записей в этой таблице может быть

zyid  styid 
qrst1234 abcd1230 
abcd9876 abcd1231 
pqzx4569 abcd1232 
bcde0000 abcd1233 

т.е. порядка записей для zyid довольно случайный.

Теперь предположим, что я выдаю

SELECT styid FROM `styles` WHERE zyid in ['abcd9876','bcde0000'] 

результат я получаю

abcd1231 
abcd1233 

т.е. строки упорядочены таким же образом, как В пункте моего SQL заявления.

Мой вопрос в том, что я могу полагаться на это всегда в этом случае (до тех пор, пока я правильно заказываю записи предложения IN)?

Если это когда-либо терпит неудачу, и я в конечном итоге неправильно сопоставляю стили, конечные результаты могут быть полностью искажены. Альтернативой было бы сделать

SELECT zyid,styid 

вместо

SELECT styid 

, а затем сделать немного больше работы по результатам, чтобы гарантировать правильное отображение.

+0

Я думаю, но я не уверен, поэтому нет ответа, что поведение не определено. Нет необходимости в какой-либо реализации, чтобы заказывать ваши результаты, если вы не просите об этом. Поэтому, пока реализация сервера _might_ дает вам последовательные результаты, вы можете и не должны полагаться на него – Nanne

ответ

5

Вы можете попробовать:

SELECT styid 
    FROM `styles` 
    WHERE zyid IN ['abcd9876','bcde0000'] 
ORDER BY FIELD(zyid, 'abcd9876','bcde0000') 
+0

Спасибо. Это похоже на работу - я подозреваю, что, помимо того, что он является более надежным способом делать вещи, он также будет быстрее, поскольку функция сортировки (массив) PHP может быть вполне сеяной. – DroidOS

-2

Просто добавьте «заказ» п в конце, например,

SELECT styid FROM `styles` 
WHERE zyid in ['abcd9876','bcde0000'] 
ORDER BY styid 
+0

-1 Не получится. Этот оператор теряет желаемый порядок. – TheCarver

+0

@PaparazzoKid: Мне не было ясно, что ОР хотел сохранить этот порядок. Что если один раз запрос был написан «где zyid в ['abc', 'def'] 'и один раз', ​​где zyid в ['def', 'abc'] '? Как создается предложение «in»? Возможно, должно быть отдельное поле, которое определяет порядок отображения. –

+0

«строки упорядочены так же, как и предложение IN» - это дает мне понять, что это тот порядок, который требуется OP. Вы можете определить порядок отображения так же, как и принятый ответ. – TheCarver

0

AFAIK вы не можете полагаться, потому что в конце концов СУБД оптимизатор решает, что для отображения первого.

2

Нет, вы не можете зависеть от результатов быть в порядке IN содержания. Вот почему:

  • Каждая строка проверяется в порядке, основанном на самом эффективном заказе, который выбирает оптимизатор запросов. Если у вас нет другого условия в вашем предложении WHERE, и вы просматриваете все столбцы (или не имеете индексов, отличных от PRIMARY), это означает, что оптимизатор выбирает сканирование таблицы, поэтому он максимально эффективно считывает все строки. В вашем результате это будет порядок вашего первого выхода.
  • Для каждая строка, она выполняет binary search записей в предложении IN. Это делает поиск (для каждой строки) достаточно эффективным, но не меняет порядок строк.

Короче говоря, порядок строк вы получаете, когда вы используете IN положения ничем не отличается от того, вы получите без помощи предложений IN, но вы можете повлиять на этот порядок, изменив заявление других способов, например, используя ORDER BY, что дает вам максимальный контроль; или (если у вас есть другие индексы), используя другие элементы в вашем заявлении, которые изменяют способ чтения оптимизатором строк.

+0

Благодарим вас за понимание, Джереми. – DroidOS

Смежные вопросы