2015-03-02 3 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 | 

Я хочу оптимизированной и лучший способ, чтобы сравнить стоимость книг в год (2013 и 2014), и быть в состоянии вывести его в HTML-таблицу с помощью PHP. Это, как я хотел бы, чтобы она появилась в HTML таблице

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

Это то, что я сделал:

  1. я первый запрашиваемых данных только для 2013
  2. , а затем запрашиваемых данных только для 2014
  3. Я сделал сравнение в 2014 году в то время как оператор

ошибки я имел 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

, что у пытался до сих пор? –

+0

И у вас есть только 3 года? –

+0

Годы могут быть больше, но для лучшего понимания я использовал только 3 года – George

ответ

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

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

+0

@George Okey, тогда не нужно понижать, я просто сказал, что это так. В любом случае, вы всегда хотите последние два года или все годы? – Pinx0

+0

@George проверить это сейчас. – Pinx0

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

EDIT: Я не слишком силен в 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

+0

Итак, см. Править выше. – Strawberry

Смежные вопросы