2016-10-03 5 views
1

У меня есть этот вид таблицы:MySQL или PHP Преобразование строк в столбцы

enter image description here

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

Я также попытался удалить отличный от моего кода ниже, но он не работает. Есть предположения?

CREATE DEFINER=`root`@`localhost` PROCEDURE `test`() 
BEGIN 
SET group_concat_max_len=2048; 
SET @sql = NULL; 

SELECT 
    GROUP_CONCAT(DISTINCT 
    CONCAT(
     'MAX(IF(month = ''', 
     month, 
     ''', amount, NULL)) AS ', 
     month 
    ) 
) INTO @sql 
FROM tmp_results; 

SET @sql = CONCAT('SELECT r.account, 
          r.region, ', 
          @sql, ' 
        FROM tmp_results r 
        LEFT JOIN accounts AS a 
        on r.account_id = a.id 
        GROUP BY r.account'); 

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

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

+0

«Не работает» не очень конкретно: что не работает или какая ошибка вы получаете? В зависимости от конфигурации вашего сервера (например, конфигурации по умолчанию 5.7) вам может потребоваться изменить параметр 'r.region' на' max (r.region) как регион 'в' select' или использовать 'GROUP BY r.account, r. region ', но в противном случае код с первого взгляда выглядит корректно (кроме того, если не проверять, является ли 'tmp_results' или, скорее,' @ sql' пустым, это приведет к ошибке в этом случае, но это не похоже проблема здесь, и это не сработает, если у вас есть недопустимые значения для 'month', например' '' 'или содержащие пробелы,' -', ...). – Solarflare

+0

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

+0

Он работает, просто не вернул результат, который я ожидал – Dhenn

ответ

1

Если вы хотите иметь раздельные колонки для ваших лет тоже, вы должны добавить год (рассчитывается от вашей колонки date) для динамического кода SQL:

CREATE DEFINER=`root`@`localhost` PROCEDURE `test`() 
BEGIN 
    SET group_concat_max_len=2048; 
    SET @sql = NULL; 

    SELECT GROUP_CONCAT(DISTINCT CONCAT(
     'MAX(IF(month = ''', 
     month, 
     ''' and year(date) = ', 
     year(date), 
     ', amount, NULL)) AS `', 
     month, 
     '_', 
     year(date), 
     '`' 
    ) 
    order by date 
) INTO @sql 
    FROM tmp_results; 

    if coalesce(@sql,'') != '' then 
    set @sql = concat(', ', @sql); 
    end if; 

    SET @sql = CONCAT(
    'SELECT r.account, 
    r.region ', 
    coalesce(@sql,''), 
    ' FROM tmp_results r 
    LEFT JOIN accounts AS a 
    on r.account_id = a.id 
    GROUP BY r.account, r.region'); 

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

Столбцы будет называться как January_2017, и я добавил order by date, в противном случае они обычно были бы неупорядоченными.

Я добавил group by r.region, иначе это не сработает, если на вашем сервере включено only_full_group_by (значение по умолчанию, начиная с MySQL 5.7).

И я добавил тест для пустых таблиц (что в противном случае привело бы к ошибке). Если вам это не нужно и скопируйте только часть моего кода в ваш, помните о недостающей запятой после r.region в SET @sql = CONCAT('SELECT r.account, r.region ' по сравнению с вашим кодом, возможно, вам придется добавить его снова.

Поскольку код для каждого месяца имеет длину около 80, вам может потребоваться увеличить group_concat_max_len в соответствии с вашим самым большим возможным запросом.

+0

Ничего себе, ты так здорово! Спасибо, ты решил мою проблему. У меня появилась идея. Сначала вы делаете год и месяц одной строкой, поэтому ее нельзя рассматривать как повторяющиеся значения. – Dhenn

+0

Привет, У меня проблемы с установкой оператора where, и мой параметр должен быть строкой, эта часть: – Dhenn

+0

SET @sql = CONCAT ( 'SELECT r.account as Account, r.region as Region, SUM (r.сумма), как Total ' сливаются (@sql, ''), 'ОТ tmp_results г LEFT JOIN счета в качестве на r.account_id = a.id где a.ABE =', человек, ' GROUP BY r.account, r.region ЗАКАЗАТЬ r.account_id '); – Dhenn

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