如何将表中的数据与当前年份和过去一年进行比较

时间:2015-03-02 07:49:14

标签: php mysql

我在MySQL表中有一些数据,我试图用当前年份值和过去一年的时间来比较这些数据。

Books
|   id  |   Name    |
|   01  |   Maths   |
|   02  |   English |   

BooksTable
| Books |   value   |   Year    |
| 01    |   40      |   2012    |
| 02    |   30      |   2012    |
| 02    |   50      |   2013    |
| 01    |   50      |   2013    |
| 01    |   60      |   2014    |

我想要一种优化的更好的方法来比较一年(2013年和2014年)的图书价值,并能够通过php将其输出到html表格中。 这就是我希望它出现在HTML表格中的方式

HTML TABLE
| BOOKS  |  2013    |   2014    |
| Maths  |   50     |   60      |
| English|   50     |   -       |

这就是我所做的:

  1. 我首先查询了2013年的数据
  2. 然后仅查询2014年的数据
  3. 我在2014年的声明中做了比较
  4. 我遇到的错误 1.如果2014查询返回空,则所有查询都为空,因为2013查询的输出依赖于2014查询

    更新 请这是我试过的

    //query for the year 2013
    SELECT
        a.id,
        a.name,
        b.books,
        b.value
    FROM
        BOOKS a
    JOIN
        BooksTable b
    ON
        a.id=b.books
    WHERE
        year=2013
    
    
    //query for the year 2014
    SELECT
        a.id,
        a.name,
        b.books,
        b.value
    FROM
        BOOKS a
    JOIN
        BooksTable b
    ON
        a.id=b.books
    WHERE
        year=2014
    

    拜托,我知道我做错了什么,有没有一个优化的更好的方法呢?如果有人可以提供帮助,我将不胜感激。感谢。

5 个答案:

答案 0 :(得分:1)

您可以使用以下内容:

SELECT b.Name, IFNULL(bt1.value, '-') as PastYear, IFNULL(bt2.value, '-') as CurrentYear
FROM Books b
LEFT JOIN BooksTable bt1 ON b.id=bt1.Books AND bt1.Year = (SELECT bt1y.Year FROM BooksTable bt1y GROUP BY bt1y.Year ORDER BY bt1y.Year DESC LIMIT 1,1)
LEFT JOIN BooksTable bt2 ON b.id=bt2.Books AND bt2.Year = (SELECT bt2y.Year FROM BooksTable bt2y GROUP BY bt2y.Year ORDER BY bt2y.Year DESC LIMIT 0,1)

这将以您想要在html中显示的方式返回数据,因此只需循环一次:

output

答案 1 :(得分:1)

我只会执行最简单的查询,并处理PHP中的显示问题(未显示)。

DROP TABLE IF EXISTS Books;

CREATE TABLE books
(book_id  INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,Name    VARCHAR(12) NOT NULL 
);
INSERT INTO books VALUES
(01  ,'Maths'),
(02  ,'English');

DROP TABLE IF EXISTS book_values;

CREATE TABLE book_values
(book_id INT NOT NULL 
,value   INT NOT NULL
,Year    INT NOT NULL
,PRIMARY KEY(book_id,year)
);

INSERT INTO book_values
VALUES
(01    ,40      ,2012    ),
(02    ,30      ,2012    ),
(02    ,50      ,2013    ),
(01    ,50      ,2013    ),
(01    ,60      ,2014    );

SELECT b.*,v.value,v.year FROM books b JOIN book_values v ON v.book_id = b.book_id WHERE v.year IN (2013,2014);
+---------+---------+-------+------+
| book_id | Name    | value | year |
+---------+---------+-------+------+
|       1 | Maths   |    50 | 2013 |
|       1 | Maths   |    60 | 2014 |
|       2 | English |    50 | 2013 |
+---------+---------+-------+------+
编辑:我不是太擅长PHP或操纵其中的数组,但是这样......

<?php

include('path/to/connection/statem.ent');

$query = "
SELECT b.*
     , v.value
     , v.year
  FROM books b
  JOIN book_values v
    ON v.book_id = b.book_id
 WHERE v.year IN (2013,2014)
 ORDER
    BY b.book_id
     , v.year;";

$old_array = array();

$result = mysqli_query($db,$query);

while($row = mysqli_fetch_assoc($result)){
$old_array[] = $row;
}

$new_array = Array();

foreach( $old_array as $v )
{
    if(!isset( $new_array[$v["Name"]][$v["year"]] ))
    {
        $new_array[$v["Name"]][$v["year"]] = 0;
    }
    $new_array[$v["Name"]][$v["year"]] += $v["value"];
}
print_r($new_array);

?>

...会生成这样的数组......

Array
(
    [Maths] => Array
        (
            [2013] => 50
            [2014] => 60
        )

    [English] => Array
        (
            [2013] => 50
        )

)

希望您可以弄清楚如何将其吐出到html表中。

答案 2 :(得分:1)

以我自己的方式,这就是我用php和mysql解决它的方法

    SELECT
        a.id,
        a.name,
        b.books,
        IFNULL(NULL,'0') AS  currentValue,
        IFNULL(b.value,0) as PastValue
    FROM
        `Books` a
    JOIN
        `BooksTable` b
    ON
        a.id=b.id
             and
        Year='2013'

UNION ALL

    SELECT
        a.id,
        a.name,
        b.books,
        IFNULL(b.value,0) as currentValue,
        IFNULL(NULL,0) as PastValue  

    FROM
        `Books` a
    JOIN
        `BooksTable` b
    ON
        a.id=b.id
            and
        Year='2014'

答案 3 :(得分:0)

Mysql没有生成数据透视表的功能,即将行值显示为列。你可以使用带有预处理语句的动态sql查询来完成它。

有很多教程(mysql将行数据显示为列。) 在您的情况下,以下人员应该完成这项工作。

set @sql = null;
select
  group_concat(distinct
    concat(
      'sum(case when bt.Year = ''',
      Year,
      ''' THEN bt.value ELSE 0 END) AS ',
      CONCAT('`',Year, '`')
    )
  ) into @sql
from BooksTable ;

SET @sql = concat('SELECT  b.Name,
                           ', @sql, 
                  'FROM     Books b
                            INNER JOIN BooksTable bt
                                ON b.id = bt.Books
                    GROUP   BY  b.Name');

prepare stmt from @sql;
execute stmt;
deallocate prepare stmt;

答案 4 :(得分:0)

你可以尝试这个伴侣:

DROP PROCEDURE IF EXISTS sp_calc_books;
DELIMITER //
CREATE PROCEDURE sp_calc_books (IN in_year INTEGER(4), OUT out_value       INTEGER(11))
BEGIN
    DECLARE EXIT HANDLER FOR SQLEXCEPTION
    BEGIN
        ROLLBACK;
    END;
    START TRANSACTION;
        SET @min_year = 0;

        SELECT MIN(year) INTO @min_year FROM bookstable;

        SELECT SUM(b.value) INTO out_value FROM books b
        JOIN bookstable bt ON bt.book = b.id
        WHERE bt.year BETWEEN @min_year AND  in_year;
COMMIT;
END//
DELIMITER ;  

然后你可以通过以下方式调用它:

CALL sp_calc_books(2014, @output_var);
SELECT @output_var;