2016-02-02 25 views
9

http://sqlfiddle.com/#!9/406cb/2nhận được hàng dựa trên thời gian hết hạn

Tôi có một cuốn sách bảng với loại 1, 2, 3, 4.

  • Loại 1 - sẽ ở lại trong vòng 1 giờ
  • Loại 2 - sẽ ở lại 2 giờ
  • loại 3 - sẽ ở lại trong vòng 4 giờ
  • loại 4 - sẽ ở lại trong vòng 6 giờ

Tôi làm cách nào để viết truy vấn để nhận kết quả mong muốn?

Ví dụ:

  1. nếu thời gian hiện nay là 1454411248 thì nó sẽ hiển thị tất cả các sách
  2. nếu thời gian hiện nay là 1454414847 thì không nên hiển thị loại 1 cuốn sách với unixtime = 1454411248 (hết hạn sau một giờ)
  3. nếu thời gian hiện tại là 1454418448 loại - 1, 2, 3, 4 dưới 1, 2, 4, 6 giờ hết hạn không được hiển thị (unix_time sẽ là động. Tôi đã sử dụng giá trị tĩnh chẳng hạn).

vv ..

Bảng:

CREATE TABLE `books` (
    `id` int(255) NOT NULL AUTO_INCREMENT, 
    `name` longtext NOT NULL, 
    `category` varchar(255) NOT NULL, 
    `unix_time` bigint(20) NOT NULL, 
    `time_data` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=19 ; 


INSERT INTO `books` (`id`, `name`, `category`, `unix_time`, `time_data`) VALUES 
    (1, 'book1', '1', 1454411248, '2016-02-02 05:37:28'), 
    (2, 'book2', '2', 1454411248, '2016-02-02 05:37:28'), 
    (3, 'book3', '3', 1454411248, '2016-02-02 05:37:28'), 
    (4, 'book4', '4', 1454411248, '2016-02-02 05:37:28'), 
    (5, 'book5', '1', 1454411248, '2016-02-02 05:37:28'), 
    (6, 'book6', '2', 1454411248, '2016-02-02 05:37:28'), 
    (7, 'book7', '3', 1454411248, '2016-02-02 05:37:28'), 
    (8, 'book8', '4', 1454411248, '2016-02-02 05:37:28'), 
    (9, 'book9', '1', 1454497648, '2016-02-03 05:37:28'), 
    (10, 'book10', '2', 1454497648, '2016-02-03 05:37:28'), 
    (11, 'book11', '1', 1454497648, '2016-02-03 05:37:28'), 
    (12, 'book12', '2', 1454497648, '2016-02-03 05:37:28'), 
    (13, 'book13', '3', 1454497648, '2016-02-03 05:37:28'), 
    (14, 'book14', '4', 1454497648, '2016-02-03 05:37:28'), 
    (15, 'book15', '1', 1454497648, '2016-02-03 05:37:28'), 
    (16, 'book16', '2', 1454497648, '2016-02-03 05:37:28'), 
    (17, 'book17', '3', 1454497648, '2016-02-03 05:37:28'), 
    (18, 'book18', '4', 1454497648, '2016-02-03 05:37:28'); 

Query:

SELECT *, 
    CASE category 
     WHEN '1' THEN '1454407648' 
     WHEN '2' THEN '1454404048' 
     WHEN '3' THEN '1454396848' 
     WHEN '4' THEN '1454389648' 
    END as category 
from books 
where unix_time >1454411248 
+0

@RyanVincent Hi Ryan. Tôi đã cập nhật sqlfiddle. Nhưng truy vấn của tôi thực sự tệ. Tôi sẽ thử truy vấn lồng nhau ngay bây giờ và cập nhật lại. – jason

+0

Nó không hiển thị cateogory 2,3,4 – jason

+0

@ hjpotter92 thực hiện – jason

Trả lời

4

Trước hết, bạn cần một bảng để liên hệ category giá trị của bạn để duration giá trị của bạn. Bạn có thể tạo một bảng vật lý, hoặc bạn có thể sử dụng một truy vấn phụ như thế này để tạo ra một bảng ảo.

select 1 as category, 1 as duration UNION ALL 
    select 2,2 UNION ALL select 3,4 UNION ALL select 4,6 

Điều này tạo ra bảng tra cứu nhỏ sau đây.

|| *category* || *duration* || 
||   1 ||   1 || 
||   2 ||   2 || 
||   3 ||   4 || 
||   4 ||   6 || 

Tiếp theo, bạn cần tham gia bảng tra cứu đó với bảng books, như vậy. Truy vấn này cũng có thể bao gồm một cột expiration, như được hiển thị.

select b.*, 
     d.duration, 
     FROM_UNIXTIME(unix_time) + INTERVAL d.duration HOUR expiration 
    from books b 
    join (select 1 as category, 1 as duration UNION ALL 
     select 2,2 UNION ALL select 3,4 UNION ALL select 4,6 
     ) d ON b.category = d.category 

Cuối cùng, bạn thêm mệnh đề WHERE để lọc ra các hàng chưa hết hạn.

select b.*, 
      d.duration, 
     FROM_UNIXTIME(unix_time) + INTERVAL d.duration HOUR expiration 
    from books b 
    join (select 1 as category, 1 as duration UNION ALL 
     select 2,2 UNION ALL select 3,4 UNION ALL select 4,6 
     ) d ON b.category = d.category 
    where FROM_UNIXTIME(unix_time) + INTERVAL d.duration HOUR >= '2016-02-03 08:00:00' 

Trong ví dụ này tôi đã sử dụng 2016-02-03 08:00:00 làm thời gian hiện tại. Bạn có thể, trong một hệ thống sản xuất, sử dụng NOW().

Bạn cũng sẽ thông minh khi sử dụng phiên bản sargable của mệnh đề where.

where unix_time >= UNIX_TIMESTAMP('2016-02-03 08:00:00' - INTERVAL d.duration HOUR) 

Cuối cùng, đây là thiết kế ưu tiên, nhưng trộn DATETIME và cột dấu thời gian unix là một chút lạ.

+1

@Arth, cảm ơn khắc phục lỗi chính tả. –

+0

Xin chào. Làm thế nào có thể kiểm tra với unixtime thay vì '2016-02-03 08:00:00'? Về cơ bản tôi đã thử thêm 1454775825 bên ngoài khung thời gian unix-dấu thời gian nhưng tôi nhận được một lỗi. – jason

+0

Tôi đã thử nơi unix_time> = 1454775825-UNIX_TIMESTAMP (INTERVAL d.duration HOUR) – jason

2

Tạo và cư một bảng category:

  • loại - id, hours_to_live

Thay đổi cuốn sách để:

  • cuốn sách - id, tên, category_id, unix_time, time_data

và tham khảo bảng loại với các nước ngoài khóa category_id.

Sau đó, bạn có thể đạt được những gì bạn muốn với một đơn giản THAM GIA:

SELECT b.*, 
    FROM books b 
    JOIN category c 
    ON c.id = b.category_id 
WHERE b.unix_time >= NOW() - INTERVAL c.hours_to_live HOUR 
Các vấn đề liên quan