【问题标题】:Pivot MySQL rows to columns in view将 MySQL 行旋转到视图中的列
【发布时间】:2011-05-17 02:31:54
【问题描述】:

我有以下表格:日期、期间、价格、品牌、车辆。

Price 模型属于 Day 和 Period。

数据库架构:

CREATE TABLE `days` (
  `id` int(3) NOT NULL AUTO_INCREMENT,
  `low` int(11) NOT NULL DEFAULT '0',
  `high` int(11) DEFAULT '0',
  `brand_id` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
);
CREATE TABLE `periods` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `start` date NOT NULL DEFAULT '0000-00-00',
  `finish` date NOT NULL DEFAULT '0000-00-00',
  `brand_id` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
);
CREATE TABLE `brands` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `brand` varchar(255) NOT NULL DEFAULT '',
  `slug` varchar(20) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
);
CREATE TABLE `vehicles` (
  `id` int(9) NOT NULL AUTO_INCREMENT,
  `size_id` int(11) DEFAULT NULL,
  `brand_id` int(11) DEFAULT NULL,
  `slug` varchar(50) NOT NULL,
  `model` varchar(50) DEFAULT NULL,
  `image` varchar(50) DEFAULT NULL,
  `short_specs` text,
  `specs` text,
  `publish` tinyint(1) DEFAULT '1',
  PRIMARY KEY (`id`)
);
CREATE TABLE `prices` (
  `id` int(3) NOT NULL AUTO_INCREMENT,
  `vehicle_id` int(3) NOT NULL DEFAULT '0',
  `day_id` int(3) NOT NULL DEFAULT '0',
  `period_id` int(3) NOT NULL DEFAULT '0',
  `price` decimal(10,2) NOT NULL DEFAULT '0.00',
  PRIMARY KEY (`id`)
);

我正在为 Day 和 Period 模型使用 virtualFields:

// day.php
var $virtualFields = array(
    'name' => "CONCAT(Day.low,IF(Day.high IS NULL, '+', ' to '),IF(Day.high IS NULL, '', Day.high))"
);

// period.php  dates are localized using setLocale and strftime in afterFind()
var $virtualFields = array(
    'name' => "CONCAT(Period.start,'|', Period.finish)"
);
function afterFind($results) {
    foreach ($results as $key => $val) {
        if (isset($val['Period']['name'])) {
            $dates = explode('|',$val['Period']['name']);
            $results[$key]['Period']['name'] = strftime('%d %b %Y',strtotime($dates[0])). ' – ' . strftime('%d %b %Y',strtotime($dates[1]));
        }
    }
    return $results;
}

如果我这样做的话,在价格模型中:

function price($id) {
    $this->set('prices', $this->find('all',array('conditions' => ('Price.vehicle_id' => $id))));
}

这显示在视图中

日间价格
2011 年 5 月 1 日至 20 日 2011 年 8 月 31 日 87.00 美元
21 至 27 日 2011 年 5 月 1 日至 2011 年 8 月 31 日 $66.00
28+ 2011 年 5 月 1 日至 2011 年 8 月 31 日 $63.00
2011 年 9 月 1 日至 20 日至 2011 年 9 月 30 日 177.00 美元
21 至 27 日 2011 年 9 月 1 日至 2011 年 9 月 30 日 $165.00
28+ 2011 年 9 月 1 日至 2011 年 9 月 30 日 $155.00
5 - 20 2011 年 10 月 1 日至 2011 年 10 月 31 日 $322.00
21 至 27 日 2011 年 10 月 1 日至 2011 年 10 月 31 日 $310.00
28+ 2011 年 10 月 1 日至 2011 年 10 月 31 日 $300.00

我该如何呈现这样的数据?

 5 - 20 天 21 - 27 天 28+ 天
2011 年 5 月 1 日至 2011 年 8 月 31 日 $87.00 $66.00 $63.00
2011 年 9 月 1 日至 2011 年 9 月 30 日 $177.00 $165.00 $155.00
2011 年 10 月 1 日至 2011 年 10 月 31 日 $322.00 $310.00 $300.00

我一直在尝试了解pivot tables,但在CakePHP 中很难做到这一点。任何建议将不胜感激。

【问题讨论】:

    标签: mysql cakephp


    【解决方案1】:

    设法弄明白了。这很有帮助:How to pivot a MySQL entity-attribute-value schema

    $prices = $this->Price->find('all',array(
        'conditions'=>array(
            'Price.vehicle_id'=>$id
        ),
        'fields'=>( //GROUP_CONCAT days and prices and separate with colon
            "GROUP_CONCAT( 
                CONCAT_WS(':',
                    CONCAT(`Day`.`low`,IF(`Day`.`high` IS NULL, '+', ' to '),IF(`Day`.`high` IS NULL, '', `Day`.`high`)),
                    `Price`.`price`
                )
                ORDER BY `Day`.`low`
            ) AS prices, 
            (CONCAT(`Period`.`start`,'|', `Period`.`finish`)) AS `period_name`"
        ),
        'group' => 'Period.id',
        'order' => 'Period.start'
        )
    );
    

    $prices 看起来像:

    array(
        array(
            array(
                'prices' => 'days:price,days:price,days:price,days:price...',
                'period_name' => 'yyy-mm-dd|yyyy-mm-dd'
            ),
            ...
    

    【讨论】:

      【解决方案2】:

      Mark Story 写了一篇标题为"Creating easy reports with pivot tables" 的博文,很可能会对您有所帮助。最重要的部分是在查询中为您想要的每一列创建一个单独的字段,然后使用带有 IF 的字段的表达式来仅选择应该在该列中使用的那些行。

      【讨论】:

        猜你喜欢
        • 2016-06-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-08
        • 2011-02-18
        相关资源
        最近更新 更多