2010-06-01 6 views
3

Можно ли возвращать группы как ассоциативный массив? Я хотел бы знать, возможно ли чистое SQL-решение. Обратите внимание, что я выпускаю, что я мог бы сделать вещи более сложными без необходимости, но это в основном для того, чтобы дать мне представление о силе SQL.SQL return ORDER BY result в виде массива

Моя проблема: у меня есть список слов в базе данных, которые следует сортировать по алфавиту и сгруппировать в отдельные группы в соответствии с первой буквой слова.

Например:

ape 
broom 
coconut 
banana 
apple 

должен быть возвращен в

array(
'a' => 'ape', 'apple', 
'b' => 'banana', 'broom', 
'c' => 'coconut' 
) 

так что я могу легко создать отсортирован списки по первой букве (т.е. нажав «А» показывает только слова, начиная с «B «с b и т. д. Это должно облегчить мне загрузку всего в один запрос и создание отсортированного списка на основе JavaScript, то есть без необходимости перезагрузки страницы (или использования AJAX).

Примечания: Я использую PostgreSQL, но решение для MySQL было бы неплохо, поэтому я могу попытаться перенести его в PostgreSQL. Язык сценариев - это PHP.

+0

Я бы сказал, что это классический пример того, что не должно выполняться в SQL, а скорее у клиента, получающего результат; SQL может гарантировать, что результат будет отсортирован, что делает красиво оформление набора результатов тривиальным. – araqnid

ответ

6

MySQL:

SELECT LEFT(word, 1) AS first_letter, 
    GROUP_CONCAT(word) AS word_list 
FROM MyTable 
GROUP BY LEFT(word, 1); 

PostgreSQL 8.4:

SELECT SUBSTRING(word FOR 1) AS first_letter, 
    ARRAY_TO_STRING(ARRAY_AGG(word), ',') AS word_list 
FROM MyTable 
GROUP BY SUBSTRING(word FOR 1); 

См http://mssql-to-postgresql.blogspot.com/2007/12/cool-groupconcat.html больше о эмуляции MySQL, GROUP_CONCAT() в PostgreSQL.

См. http://www.postgresonline.com/journal/index.php?/archives/126-PostgreSQL-8.4-Faster-array-building-with-array_agg.html для получения дополнительной информации о ARRAY_AGG().

+0

+1: Вау, это красноречиво –

+1

Я отредактировал пример PostgreSQL после того, как я обнаружил, что PostgreSQL 8.4 поддерживает «ARRAY_AGG()», поэтому вам не нужно объявлять собственную собственную функцию агрегации. Если вы используете PostgreSQL <8.4, см. блог, на который я ссылаюсь для решений. –

+0

Если вы можете использовать функции windowing в PostgreSQL, используйте их вместо этого. Будет намного проще переносить дорогу, когда MySql вырастет достаточно, чтобы поддержать их тоже. –

0

Запуск 26 отдельных запросов. Или запустите один запрос и отделите результаты по алфавиту на стороне сервера.

0

Вы знакомы с синонимом LIKE?

как в

SELECT * FROM words WHERE col LIKE a% ORDER BY col 

даст вам коэффициенты а в порядке и так далее. Постройте хэш соответственно.

+0

Да, но я бы хотел, чтобы эта функция была в одном запросе, если это было возможно. – EarthMind

+0

Один запрос не всегда хорош как mutliple-запросы. – Lizard

+0

Мне нравится решение Билла, но оно требует уровня знания синтаксиса SQL. Более интеллектуальный запрос размера укуса может быть предпочтительным для вашей ситуации развития с точки зрения удобочитаемости/ремонтопригодности и т. Д. – Carl

0

Я не эксперт PostgreSQL (или пользователь), но я верю в более поздних версиях вы можете сделать что-то вроде этого:

SELECT 
    ROW_NUMBER() OVER (PARTITION BY SUBSTRING(whatever from 1 for 1) ORDER BY whatever) AS __ROW, 
    whatever 
FROM yourtable; 

Это ANSI SQL. Я еще не знаю, какая поддержка на MySql. Oracle и SQL Server работают с этим синтаксисом, и я слышал, что через Google PostgreSQL 8.4 поддерживает функции окон.

+0

FWIW, MySQL не поддерживает функции оконной обработки. :-( –

+0

Кажется, PostgreSQL 8.4 и выше делают функции поддержки окна. Источник: postgresql.org. – EarthMind

+0

Кажется, что это не работает так, как нужно, так как возвращает номера строк, которые не группируют правильные слова друг с другом. – EarthMind