2015-03-02 53 views
2

我在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 | 

我想要一个优化,更好的方式通过PHP比较在今年(2013年和2014年)的图书的价值,并能输出成一个HTML表格。 这是我希望它出现在HTML表格

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

这是我做过什么:

  1. 我第一次查询的数据仅为2013
  2. ,然后查询数据只2014
  3. 我提出的2014年相比,while语句

的错误我 个1.所有查询运行空,如果2014年的查询返回空,因为输出为2013查询依赖2014年查询

UPDATE 请这就是我试图

//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 

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

+0

什么ü试图到目前为止解决呢? – 2015-03-02 07:50:55

+0

而你只有3年? – 2015-03-02 07:53:21

+0

这些年可能更多,但为了更好地理解,我仅使用了3年 – George 2015-03-02 07:54:48

回答

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' 
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; 
+0

输出是html,所以在这里不需要mysql数据透视表。 PHP可以完成这项工作。 – Strawberry 2015-03-02 08:40:04

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

+0

这些年可能更像2015年和2014年,它不应该只是2013年和2014年。我用这个来最好地阐明我想要的东西。 – George 2015-03-02 08:44:04

+0

@George Okey然后,不需要downvote,我只是说如果是这样的话。无论如何,你总是想要过去的两年,还是全年? – Pinx0 2015-03-02 08:55:20

+0

@George现在就来看看吧。 – Pinx0 2015-03-02 09:09:38

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; 
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表格。

+0

这很酷很简单,但你会如何比较它们。 – George 2015-03-02 10:13:58

+0

因此,请参阅上面的编辑。 – Strawberry 2015-03-02 14:34:23

相关问题