2015-09-18 2 views
2

Возьмет следующую таблицу:Возврат всех различных значений столбца B в одной строке для каждого отдельного значения в колонке А

CREATE TABLE boxes (
    box integer, 
    color character varying, 
    size integer, 
    ... 
); 

где оба box и color можно предположить, не уникальные значения из небольшого набора.

Запрос эту таблицу:

SELECT color, box FROM boxes; 

результат будет что-то вроде:

+-------+-----+ 
| color | box | 
+-------+-----+ 
| blue | 2 | 
| blue | 3 | 
| blue | 4 | 
| green | 1 | 
| green | 3 | 
| red | 1 | 
| red | 2 | 
| red | 2 | 
+-------+-----+ 

Можно ли запросить эту таблицу таким образом, что результат имеет две колонки, одна с массив (или строку или список) со всеми значениями box для каждого отдельного color?

Результат должен быть чем-то вроде этого:

+-------+-----------+ 
| color | box_types | 
+-------+-----------+ 
| blue | {2,3,4} | 
| green | {1,3}  | 
| red | {1,2}  | 
+-------+-----------+ 

, где color столбец должен содержать уникальные значения, и каждая строка должна содержать только отдельные box числа в агрегированном колонке.

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

+1

, что это на самом деле не SQL способ делать вещи. Однако некоторые продукты dbms имеют функциональность, например GROUP_CONCAT и STUFF. – jarlh

+0

Я полагаю, кто-то должен объединить все ответы в один ... – xpy

+0

Да, это намерение. –

ответ

1

Ну, в MySQL вы можете сделать следующее:

select color, group_concat(box) from tbl group by color 

В Oracle:

select color, wm_concat(box) from tbl group by color 
+1

Нет необходимости добавлять фигурные скобки, где в ответе для случая вы группируете столбец массива вместо одной строки.Поэтому 'SELECT color, group_concat (box) FROM box GROUP BY color;' может быть хорошо, если вы найдете способ получить только и все отдельные номера 'box' для каждого' color'. –

+0

@ClaudioFloreani: Ну, я слышал вас до этого и отредактировал ответ) – potashin

3

Попробуйте ниже.

SELECT 
    color , 
    STUFF(
     (SELECT DISTINCT ',' +CONVERT(varchar(10), box) 
      FROM boxes 
      WHERE color = a.color 
      FOR XML PATH ('')) 
      , 1, 1, '') AS box_types 
FROM boxes AS a 
GROUP BY color; 

Проверить SQL Fiddle

+0

Это правильный ответ для MS SQL Server. Обратите внимание, что фигурные скобки были в ответе, потому что это был столбец массива вместо строки. Я удалил их из вашего ответа. –

0

Прежде всего, это отрицание принципа «нормализации», другими словами, это «плохо».

Однако существуют некоторые dbms, такие как Microsoft SQL Server, которые реализуют эту возможность с предложением PIVOT (и его противоположностью UNPIVOT).

Этот пункт позволяет создать таблицу (используя пример), как это:

 
+-------+------+------+------+ 
| color | box1 | box2 | box3 | 
+-------+------+------+------+ 
| blue | 2 | 3 | 4 | 
| green | 1 | 3 | null | 
| red | 1 | 2 | null | 
+-------+------+------+------+ 
+0

Я думаю, что вам нужно знать точные - быть готовыми столбцами, чтобы использовать 'PIVOT' – xpy

+0

Современная СУБД поддерживает столбцы массивов. Если они «отрицают принцип нормализации», это не помешает пользователям получить выгоду от их использования. В конце концов, это всего лишь способ преобразования данных, чтобы они были более подходящими для ваших нужд. Возьмите случай, когда у вас есть данные, хранящиеся в одной таблице db, но вам нужно использовать их по-другому в другой таблице db. В примере «все разные номера ящиков для каждого цвета» - это не что иное, как одно значение. –

+0

Вы правы, но, как я узнал, вы не можете назвать это РСУБД, если она не находится в пятой нормальной форме. Эта таблица даже не третья !!! –

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