我在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.如果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
拜托,我知道我做错了什么,有没有一个优化的更好的方法呢?如果有人可以提供帮助,我将不胜感激。感谢。
答案 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中显示的方式返回数据,因此只需循环一次:
答案 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;