2016-11-01 4 views
1

Допустим, у меня есть таблица истории цен на продукцию, которая является цена и идентификатор продукта, со следующими записями:Показать в одной строке все записи, имеющие одинаковый идентификатор.

id price 

1  23  
2  14  
2  23  
2  20 
3  30 
3  40 

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

Что я expectis что-то вроде этого:

id priceA PriceB PriceC 

1 23  NULL NULL   
2 14  23  20  
3 30  40  NULL  
+0

Существует мало потребности в желаемом желании в наборе на основе языка. Вы ищете запрос кросс-таблицы, который в настоящее время не существует в mysql. Оформить заказ http://stackoverflow.com/questions/15997090/crosstab-view-in-mysql –

+0

Возможно, вы обнаружили, что поиск возвращаемого xml из mysql полезен. Достаточно просто преобразовать xml в json, если вы хотите использовать данные в веб-браузере. https://www.google.com.au/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=mysql%20return%20xml –

+0

Простой GROUP_CONCAT, как в решении @ RicardoOrtegaMagaña, или если вы хотите его отдельные столбцы это можно сделать, но вы должны заранее определить количество столбцов. –

ответ

1

Это не правильный способ делать вещи вы должны использовать отдельную таблицу и попробовать некоторые первичные ключи.

Предположим, у вас есть таблица poductprice с идентификатором и цены делают вид, как

CREATE VIEW history AS ( 
    SELECT 
    id, 
    CASE WHEN id = "1" THEN price END AS priceA, 
    CASE WHEN id = "2" THEN price END AS priceB, 
    CASE WHEN id = "3" THEN price END AS priceC 
    FROM productprice 
); 

SELECT * FROM history; 
+0

Downvoted. Ответ не имеет ничего общего с вопросом, и это не что иное, как технический беспорядок. «Попробуйте некоторые первичные ключи»? «сделать вид»? шутки в сторону? –

+0

Я просто предлагаю ему использовать ключи bro, и это правильное решение, что он хочет –

+0

Сколько первичных ключей есть для одной таблицы? если у нас нет первичного ключа в таблице, мы не можем ответить на вопрос? Если у нас нет привилегии CREATE VIEW, мы не можем ответить на вопрос? Сколько строк возвращает ваш запрос? –

0

Вы могли бы хотеть что-то вроде этого:

SELECT id, GROUP_CONCAT(string SEPARATOR ' ') FROM priceHistory GROUP BY id; 
1

Это требование действительно плохо подходит для SQL, но это может быть достигнуто с большим количеством возиться с участием «динамического sql» и вымыванием для достижения эквивалента row_number(). т. е. Было бы легче достичь с помощью CTE и row_number(), возможно, если MySQL получит бит, это может быть повторно рассмотрено.

В любом случае, требуется получить цены в пронумерованные столбцы, поэтому первая цена каждого продукта идет в первом столбце, вторая цена во втором столбце и так далее. Поэтому нам нужно в первом случае указать число строк, которые впоследствии будут преобразованы в столбцы. В MySQL это можно сделать с помощью переменных, например:

   select 
        @row_num := IF(@prev_value = p.id, @row_num+1, 1) AS RowNumber 
       , id 
       , price 
       , @prev_value := p.id 
       from (select distinct id, price from pricehistory) p 
       CROSS JOIN (SELECT @row_num :=1, @prev_value :='') vars 
       order by id, price 

Так что фрагмент кода используется дважды в следующем. В верхней части он формирует набор выражений case, которые будут делать преобразование. В нижней части мы объединяем эти выражения case с остальной частью запрашиваемого sql и затем выполняем его.

set @sql = (
SELECT GROUP_CONCAT(col_ref) 
     FROM (
      select distinct 
     concat(' max(case when RowNumber=',RowNumber,' then Price else NULL end) as c',RowNumber) col_ref 
      from (
        select 
         @row_num := IF(@prev_value = p.id, @row_num+1, 1) AS RowNumber 
        , id 
        , price 
        , @prev_value := p.id 
        from (select distinct id, price from pricehistory) p 
        CROSS JOIN (SELECT @row_num :=1, @prev_value :='') vars 
        order by id, price 
       ) d 
      order by `RowNumber` 
      ) dc 
    ); 

set @sql = concat('select id,', @sql, 
        ' from (
        select 
         @row_num := IF(@prev_value = p.id, @row_num+1, 1) AS RowNumber 
        , id 
        , price 
        , @prev_value := p.id 
        from (select distinct id, price from pricehistory) p 
        CROSS JOIN (SELECT @row_num :=1, @prev_value :='''') vars 
        order by id, price 
       ) d 
        Group By `id`'); 

#select @sql 
PREPARE stmt FROM @sql; 
EXECUTE stmt; 
\\ 

В результате этого, на основе выборки заданного является:

id c1  c2  c3 
1 1 23  NULL NULL 
2 2 14  20  23 
3 3 30  40  NULL 

Это решение может быть проверено и повторно запустить по адресу: http://rextester.com/AYAA36866

Примечание полностью генерируется SQL читается как это :

select id 
, max(case when RowNumber=1 then Price else NULL end) as c1 
, max(case when RowNumber=2 then Price else NULL end) as c2 
, max(case when RowNumber=3 then Price else NULL end) as c3 
from (
        select 
         @row_num := IF(@prev_value = p.id, @row_num+1, 1) AS RowNumber 
        , id 
        , price 
        , @prev_value := p.id 
        from (select distinct id, price from pricehistory) p 
        CROSS JOIN (SELECT @row_num :=1, @prev_value :='') vars 
        order by id, price 
     ) d 
Group By `id` 
Смежные вопросы