动态数据透视表问题

时间:2017-10-14 16:23:27

标签: php mysql

我的查询存在一些问题,因为它在指定日期之间生成所需数据(在实时它是2个日期字段(date_from和date_to),但数据的顺序顺序错误。例如,它将出现< / p>

JAN 2017 | MARCH 2017 | APRIL 2017 | FEB 2017

最令人困惑的问题是它会在您搜索的内容之外生成数据。例如,如果您在1-1-2017之间搜索到日期,它会在数据中添加12月,但数据库中没有包含12月记录的数据。

用于生成动态数据透视表的代码是:

$sql = "
    SELECT
      GROUP_CONCAT(DISTINCT
        CONCAT(
          'SUM(CASE WHEN EXTRACT(".$period." FROM redeem_pledge) = ',
          EXTRACT(".$period." FROM redeem_pledge),
          ' THEN AMOUNT else 0 END) AS `',
          EXTRACT(".$period." FROM redeem_pledge),
          '`'
        )
      ) AS `pivot_columns`
    FROM record_pledge
    WHERE redeem_pledge BETWEEN ? AND ?
    ORDER BY redeem_pledge asc
";
$stmt = $pdo->prepare($sql);
$date_from = $this->input->get('date_from') ? $this->input->get('date_from') : '2017-05-01';
$date_to   = $this->input->get('date_to') ? $this->input->get('date_to') : date('Y-m-d');
$stmt->execute([$date_from, $date_to]);
$row = $stmt->fetch();
$stmt->closeCursor();
$pivot_columns = $row['pivot_columns'];

$sql = "
    SELECT title AS `Pledge Purpose`, {$pivot_columns}
    FROM record_pledge t1
    JOIN setting_pledge_purpose ON t1.purpose_pledge = setting_pledge_purpose.id
    WHERE t1.redeem_pledge BETWEEN ? AND ?
    GROUP BY title asc WITH ROLLUP
";

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

添加数据和无组织数据的图像:

enter image description here

更新回复SQL-SEARCH来自01-01-2017(JAN) - 15-10-2017(OCT):

SELECT title AS `Pledge Purpose`,
SUM(CASE WHEN EXTRACT(YEAR_MONTH FROM redeem_pledge) = 201701 THEN AMOUNT else 0 END) AS `201701`,
SUM(CASE WHEN EXTRACT(YEAR_MONTH FROM redeem_pledge) = 201702 THEN AMOUNT else 0 END) AS `201702`,
SUM(CASE WHEN EXTRACT(YEAR_MONTH FROM redeem_pledge) = 201704 THEN AMOUNT else 0 END) AS `201704`,
SUM(CASE WHEN EXTRACT(YEAR_MONTH FROM redeem_pledge) = 201705 THEN AMOUNT else 0 END) AS `201705`,
SUM(CASE WHEN EXTRACT(YEAR_MONTH FROM redeem_pledge) = 201706 THEN AMOUNT else 0 END) AS `201706`,
SUM(CASE WHEN EXTRACT(YEAR_MONTH FROM redeem_pledge) = 201708 THEN AMOUNT else 0 END) AS `201708`,
SUM(CASE WHEN EXTRACT(YEAR_MONTH FROM redeem_pledge) = 201709 THEN AMOUNT else 0 END) AS `201709` 
FROM record_pledge t1 JOIN setting_pledge_purpose ON t1.purpose_pledge = setting_pledge_purpose.id 
WHERE t1.redeem_pledge BETWEEN ? AND ? GROUP BY title asc WITH ROLLUP

1 个答案:

答案 0 :(得分:1)

您需要将ORDER BY选项放在GROUP_CONCAT函数中,而不是SELECT查询。

此外,您需要在EXTRACT($period FROM redeem_pledge)返回的值周围加上引号。如果$period是返回日期的多个部分的单位,例如YEAR_MONTH,则需要将其作为字符串进行比较,因为它将是2017-01;如果你不引用它,它将被视为数字减法。

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

";