2016-02-02 12 views
9

http://sqlfiddle.com/#!9/406cb/2dostać wiersze na podstawie czasu wygaśnięcia

Mam książek stół z kategorii 1, 2, 3, 4.

  • Kategoria 1 - pozostanie przez 1 godzinę
  • Kategoria 2 - będzie zatrzymać się na 2 godziny
  • Kategoria 3 - pozostanie w ciągu 4 godzin
  • Kategoria 4 - pozostanie przez 6 godzin

Jak napisać zapytanie, aby uzyskać pożądane wyniki?

Np:

  1. jeśli obecny czas jest 1454411248 to powinno pokazać wszystkie książki
  2. jeśli obecny czas jest 1454414847 to nie powinien pokazać kategoria 1 książki z unixtime = 1454411248 (wygaśnięcia po godzinach)
  3. jeśli aktualny czas to 1454418448 kategoria - 1, 2, 3, 4 poniżej 1, 2, 4, 6 godzin czasu wygaśnięcia nie powinien być wyświetlany (unix_time będzie dynamiczny. Użyłem na przykład wartości statycznej).

itd ..

Tabela:

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'); 

Zapytanie:

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 Witaj Ryan. Mam aktualizację sqlfiddle. Ale moje zapytanie jest naprawdę złe. Spróbuję teraz zagnieżdżonego zapytania i zaktualizuję go ponownie. – jason

+0

To nie pokazuje cateogory 2,3,4 – jason

+0

@ hjpotter92 done – jason

Odpowiedz

4

Przede wszystkim trzeba tabelę odnosić swoje wartości category do wartości duration. Można utworzyć fizyczną tabelę lub użyć podzapytania w taki sposób, aby wygenerować wirtualny stół.

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

Powoduje to wyświetlenie poniższej tabeli wyszukiwania.

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

Następnie należy dołączyć tę tabeli odnośników do stolika books, jak tak. Ta kwerenda może również zawierać kolumnę expiration, jak pokazano.

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 

Wreszcie, dołączyć WHERE klauzuli odfiltrować niewykorzystaną wiersze. W tym przykładzie użyłem 2016-02-03 08:00:00 jako bieżącego czasu. W systemie produkcyjnym można użyć numeru NOW().

Można również użyć wersji sargable klauzuli where.

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

Wreszcie, jest to preferencja design, ale mieszanie DATETIME i unix timestamp kolumny jest trochę dziwne.

+1

@Arth, dzięki za naprawienie literówki. –

+0

Witam. W jaki sposób można przetestować z systemem uniksowym zamiast "2016-02-03 08:00:00"? Zasadniczo próbowałem dodając 1454775825 poza uchwytem unix-timestamp ale dostaję błąd. – jason

+0

Próbowałem gdzie unix_time> = 1454775825-UNIX_TIMESTAMP (INTERVAL d.duration HOUR) – jason

2

Tworzenie i wypełnianie tabeli kategorii:

  • kategoria - id, hours_to_live

Zmień książka:

  • książka - id, nazwa, category_id, unix_time, time_data

i odniesienie do tabeli kategorii z zagranicznym key category_id.

Wtedy można osiągnąć to, co chcesz z prostym DOŁĄCZ:

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 
Powiązane problemy