2017-10-17 105 views
0

我一直在为一个项目工作了大约5个星期,现在我一直在做各种各样的计算器贴子,我几乎在最后一关。动态数据透视表MYSQL不完整SQL

我有重复的数据搜索每周总结的问题,但我似乎已经想通了,但现在我的声明没有完成。 更改编号: Weekly Sum Dynamic Pivot MYSQL

这里是一个数据的小提琴。 http://sqlfiddle.com/#!9/a3610

$period = 'YEARWEEK'; 


    $sql = " 
    SELECT 
     GROUP_CONCAT(DISTINCT 
     CONCAT(
      'SUM(CASE WHEN (".$period."(date)) = ', 
      (".$period."(date)), 
      ' THEN AMOUNT else 0 END) AS `', 
      (".$period."(date)), 
      '`' 
     ) 
     ORDER BY date ASC) AS `pivot_columns` 
    FROM record_offering 
    WHERE date BETWEEN ? AND ? 
    ORDER BY date ASC 
"; 

$stmt = $pdo->prepare($sql); 
$date_from = '2017-01-01'; 
$date_to = '2017-10-01'; 
$stmt->execute([$date_from, $date_to]); 
$row = $stmt->fetch(); 
$stmt->closeCursor(); 
$pivot_columns = $row['pivot_columns']; 

$sql = " 
    SELECT title AS `Service`, {$pivot_columns} 
    from record_offering t1 
    join setting_service ON t1.service_id = setting_service.id 
    WHERE t1.date BETWEEN ? AND ? 
    GROUP BY title asc WITH ROLLUP 
"; 

$stmt = $pdo->prepare($sql); 
$stmt->execute([$date_from, $date_to]); 
$results = $stmt->fetchAll(); 
$stmt->closeCursor(); 

正如你所看到的最后一个语句不完整:

SELECT title AS `Service`, SUM(CASE WHEN (YEARWEEK(date)) = 201635 THEN AMOUNT else 0 END) AS `201635`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201703 THEN AMOUNT else 0 END) AS `201703`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201709 THEN AMOUNT else 0 END) AS `201709`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201713 THEN AMOUNT else 0 END) AS `201713`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201715 THEN AMOUNT else 0 END) AS `201715`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201717 THEN AMOUNT else 0 END) AS `201717`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201718 THEN AMOUNT else 0 END) AS `201718`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201722 THEN AMOUNT else 0 END) AS `201722`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201723 THEN AMOUNT else 0 END) AS `201723`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201725 THEN AMOUNT else 0 END) AS `201725`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201726 THEN AMOUNT else 0 END) AS `201726`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201735 THEN AMOUNT else 0 END) AS `201735`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201736 THEN AMOUNT else 0 END) AS `201736`, 
SUM(CASE WHEN (YEARWEEK(date)) = 201 
from record_offering t1 
join setting_service ON t1.service_id = setting_service.id 
WHERE t1.`date` BETWEEN ? AND ? 
GROUP BY title asc WITH ROLLUP 

我试图逃避各种方式查询,但无论是在查询完成,我的数据是重复的,或者不完全可以编译。

+1

认真考虑处理应用程序代码中的数据显示问题。它会大量简化这个查询。从我的角度来看,你现在的策略是完全回到前面 – Strawberry

+0

我的初始尝试只是一个基本的总和和组查询,然后我使用php进行了转换,但它不会将日常数据汇总到正确的位置。然后我被建议尝试枢轴 –

+0

当表示层代码可用时,我无法看到以这种方式旋转数据的要点。 – Strawberry

回答

2

GROUP_CONCAT有1024字节的限制。

使用

SET SESSION group_concat_max_len = @@max_allowed_packet

的GROUP_CONCAT查询之前。

+0

对此没有想法,目前这个项目正在共享主机上运行,​​我相信我需要root权限才能正确使用这个项目。 –

+0

@ Enoch S否你可以在没有SUPER权限或没有root权限的情况下使用此设置 –

0

为了我的思维方式,这个(或者非常喜欢它的东西)就是你所需要的这个问题的所有sql。 一切其他可以,也应该在表示层中处理。

SELECT YEARWEEK(x.date) yw 
    , x.title 
    , COALESCE(SUM(y.amount),0) total 
    FROM setting_service x 
    LEFT 
    JOIN record_offering y 
    ON y.service_id = x.id 
GROUP 
    BY yw 
    , x.id; 
+0

我的初始努力与你所说的一样。这是我发布在SA上的问题:https://stackoverflow.com/questions/45267138/datatables-dates-at-the-top-and-data-cells-going-from-left-to-right –

+0

I认为这看起来更好一些。唯一的问题是'ROLLUP' - 你可以用一点javascript来轻松完成。 – Strawberry

+0

这可能已经完成,但问题是它没有正确汇总数据。 http://www.phpwin.org/s/0xFWpF是小提琴。如果您将thead和tbody时间间隔更改为+1天,则数据是正确的,但在+1周内它不会聚合,因为第一个应该是5 –