2016-10-03 34 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默認配置),您可能必須在'select'中將'r.region'更改爲'max(r.region)as region'或使用'GROUP BY r.account,r。區域「,但除此之外,第一眼看起來,代碼看起來是正確的(除了不檢查」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.regionSET @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。量),爲總計 '中,聚結 (@sql, ''), 'FROM tmp_resultsř LEFT JOIN的賬戶作爲 上r.account_id = a.id 其中a.ABE =',人, ' GROUP BY r.account,r.region ORDER By r.account_id'); – Dhenn