Как реализовать запрос SQL, который, начиная с запроса, возвращающего несколько записей, возвращает одну запись с несколькими столбцами? - PullRequest
0 голосов
/ 02 мая 2018

Я не так в базу данных, и у меня есть следующая проблема при работе с MySql базы данных.

У меня есть такая таблица:

CREATE TABLE CommodityName (
  id                   BigInt(20) NOT NULL AUTO_INCREMENT,
  commodity_details_id BigInt(20) NOT NULL,
  language_id          BigInt(20) NOT NULL,
  commodity_name       VarChar(255) CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL,
  description          Text CHARACTER SET latin1 COLLATE latin1_swedish_ci, 
  PRIMARY KEY (
      id
  )
) ENGINE=InnoDB AUTO_INCREMENT=87 ROW_FORMAT=DYNAMIC DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci;
ALTER TABLE CommodityName COMMENT = '';

Записи в этой таблице представляют информацию о товарах на разных языках.

Товар определяется однозначно и commodity_details_id (то есть FK другой таблицы).

Определенный товар может иметь несколько записей в этой таблице CommodityName (у меня есть запись для каждого перевода на определенном языке, представленная полем language_id ). Например, у меня есть эти 2 записи:

id                   commodity_details_id language_id          commodity_name          description                                                                                                                                                                                                                                                    
-------------------------------------------------------------------------------------------------------
1                    1                    1                    Rice Asia               Rice Asia                                                                                                                                                                                                                                                      
16                   1                    3                    Umuceli Asia            Umuceli Asia                                                                                                                                                                                                                                                   

, которая представляет ту же самую информацию о товаре (обе имеют commodity_details_id = 1 ), но на 2 языках (английском и языке кинирванда). Теоретически у меня могут быть и другие языки, поэтому я могу иметь n записей для определенного товара.

Мне нужно создать запрос, в котором для указанного товара ( WHERE commodity_details_id = 1 ) он возвращает все поля commodity_name найденной записи в виде столбца одной записи.

Ссылаясь на предыдущий пример, примерно так:

commodity_details_id       commodity_name_EN      commodity_name_RWA          commodity_name_FR   
----------------------------------------------------------------------------------------------------------------
1                          Rice Asia              Umuceli Asia                null

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

Ответы [ 2 ]

0 голосов
/ 02 мая 2018

То, что вы ищете, называется Dynamic Pivot .

Посмотрите на приведенный ниже код и посмотрите, работает ли он для вас. Схема может немного отличаться в вашем случае (только имена столбцов и таблиц). Я использую commodityName, commodity_details, таблицу языков. Все, что вам нужно сделать, это передать параметр commodity_details_id во 2-й строке:

SET @sql = NULL;
SET @commodity_details_id = 1;

SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(CASE WHEN language_id = ''',
      ID,
      ''' then ''',
      (select commodity_name from commodityname where language_id = L.Id and commodity_details_id = @commodity_details_id),
      ''' end) AS ',
      Concat('Commodity_Name','_', language_name)
    )
  ) INTO @sql
from languages L;

SET @sql = CONCAT(
'SELECT commodity_details_id, '
, @sql, 
' 
FROM CommodityName
where commodity_details_id = ',@commodity_details_id,'
group by commodity_details_id;
');


PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

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

Пожалуйста, прокомментируйте, если это не работает для вас.

0 голосов
/ 02 мая 2018

Попробуйте:

SELECT commodity_details_id,
MAX(CASE WHEN language_id=1 then commodity_name else null END) commodity_name_EN,
MAX(CASE WHEN language_id=3 then commodity_name else null END) commodity_name_RWA,
MAX(CASE WHEN language_id=2 then commodity_name else null END) commodity_name_FR
FROM CommodityName
group by commodity_details_id;
...