@azerphoenix

Как лучше объединить данные из базы данных?

Доброго времени суток!
Имеется сущность Translation (Entity).

@Entity @Data
@Table(name = "translations")
public class Translation {

    @Id  @GeneratedValue(strategy = GenerationType.AUTO)
    private Long translationId;

    @Column
    private String locale;

    @Lob
    @Column(name = "messagekey", length = 3000)
    private String key;

    @Lob
    @Column(name = "messagecontent", length = 100000)
    private String content;
}


Сама таблица translations:

+----------------+-------------------------+------------+--------+
| translation_id |     messagecontent      | messagekey | locale |
+----------------+-------------------------+------------+--------+
|              1 | текст на русском        | key1       | ru     |
|              2 | text in english         | key1       | en     |
|              3 | text auf Deutsch        | key1       | de     |
|              4 | другой текст на русском | key2       | ru     |
|              5 | other text in english   | key2       | en     |
|              6 | andere text auf Deutsch | key2       | de     |
+----------------+-------------------------+------------+--------+


Задача - нужно объединить данные таким образом, чтобы в конечном счете получить примерно такую структуру:
+------------+-------------------------+-----------------------+-------------------------+
| messagekey |           ru            |          en           |           de            |
+------------+-------------------------+-----------------------+-------------------------+
| key1       | текст на русском        | text in english       | text auf Deutsch        |
| key2       | другой текст на русском | other text in english | andere text auf Deutsch |
+------------+-------------------------+-----------------------+-------------------------+


Говоря проще, нужно из вертикальной структуры таблицы перевести в горизонтальную.

Соответственно вопрос:
На каком уровне это лучше сделать?
  • На уровне MySQL (есть ли готовое решение в синтаксисе JPQL или нужно использовать nativeQuery). Если да, то что именно? GROUP_CONCAT, CONCAT, GROUP BY etc.
  • На уровне Java кода. Тогда вопрос - как итерировать по 3-м спискам одновременно? Притом, что длина списков может отличаться.


Stream.concat(listA.stream(), listB.stream()) позволяет итерировать по 2-м спискам.
Мое текущее решение, хоть и не самое хорошее...
List<Translation> translations_DE = translationService.findAllByLocale("de");
List<Translation> translations_RU = translationService.findAllByLocale("ru");
List<Translation> translations_EN = translationService.findAllByLocale("en");
List<TranslationDTO> translationDTOS = new ArrayList<>();
int len = translations_DE.size();
len = Math.max(len, translations_RU.size());
len = Math.max(len, translations_EN.size());
for (int i = 0; i < len; i++) {

    String translationKey = translations_DE.get(i).getKey();

    Long translationId_DE = translations_DE.get(i).getTranslationId();
    Long translationId_RU = translations_RU.get(i).getTranslationId();
    Long translationId_EN = translations_EN.get(i).getTranslationId();

    String translationContent_DE = translations_DE.get(i).getContent();
    String translationContent_RU = translations_RU.get(i).getContent();
    String translationContent_EN = translations_EN.get(i).getContent();

    TranslationDTO translationDTO = new TranslationDTO();
    translationDTO.setKey(translationKey);
    translationDTO.setId_DE(translationId_DE);
    translationDTO.setId_RU(translationId_RU);
    translationDTO.setId_EN(translationId_EN);
    translationDTO.setContent_DE(translationContent_DE);
    translationDTO.setContent_RU(translationContent_RU);
    translationDTO.setContent_EN(translationContent_EN);

    translationDTOS.add(translationDTO);
}


Буду рад любой подсказке! Заранее спасибо)

Я так понимаю, что это Pivot Table. Но насколько мне известно, в MySQL его и нет.
SELECT "messagekey",
       SUM("locale" = 'de') AS de,
       SUM("locale" = 'ru') AS ru,
       SUM("locale" = 'en') AS en
FROM "translations"
GROUP BY "messagekey";


Дает похожий результат... Только вместо текста из столбца messagecontent выводит цифры (я так понимаю сумму)
+------------+----+----+----+
| messagekey | de | ru | en |
+------------+----+----+----+
| key1       |  1 |  1 |  1 |
| key2       |  1 |  1 |  1 |
+------------+----+----+----+
  • Вопрос задан
  • 74 просмотра
Пригласить эксперта
Ответы на вопрос 1
@azerphoenix Автор вопроса
Вот, мое решение данного вопроса на уровне MySQL

SELECT "messagekey",
MAX(CASE WHEN ("locale"='de') THEN "messagecontent" ELSE null END ) AS de,
MAX(CASE WHEN ("locale"='ru') THEN "messagecontent" ELSE null END ) AS ru,
MAX(CASE WHEN ("locale"='en') THEN "messagecontent" ELSE null END ) AS en
FROM "translations" GROUP BY "messagekey";

Результат:
+------------+--------------------------+---------------------------+-----------------------+
| messagekey |            de            |            ru             |          en           |
+------------+--------------------------+---------------------------+-----------------------+
| key1       | text auf Deutsch         | текст на русском          | text in english       |
| key2       | andere text auf Deutsch  | другой текст на русском   | other text in english |
+------------+--------------------------+---------------------------+-----------------------+
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы