2016-02-02 7 views
9

http://sqlfiddle.com/#!9/406cb/2有効期限に基づいて行を取得し、私は、カテゴリ1、2、3とテーブルの本を持って

、4

  • カテゴリー1は、 - 1時間滞在する
  • カテゴリー2 - 意志2時間
  • カテゴリー3のために滞在 - 4時間
  • カテゴリー4のために滞在します - 6時間
012のために滞在します

希望する結果を得るためのクエリを作成するにはどうすればよいですか?

例:

  1. 現在時刻が1454411248であるならば、それは現在の時刻が1454414847であるならば、それは時間後unixtime = 1454411248(有効期限とカテゴリ1冊の本を表示してはならないすべての書籍
  2. を示すべき)
  3. 現在の時刻が1454418448の場合、有効期限の1,2,4,6時間未満のカテゴリは表示されません(unix_timeは静的な値を使用しています)。その上

..

表:

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

問合せ:

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私はsqlfiddleを更新しました。しかし、私の質問は本当に悪いです。私は今入れ子になったクエリを試し、再度更新します。 – jason

+0

それはcateogoryを表示していません2,3,4 – jason

+0

@ hjpotter92 done – jason

答えて

4

まず、あなたのduration値にごcategory値を関連付けるためにテーブルを必要としています。物理的な表を作成することも、このような副問合せを使用して仮想表を生成することもできます。

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

これにより、以下の小さなルックアップテーブルが生成されます。

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

次はそのように、あなたのbooksテーブルにそのルックアップテーブルに参加する必要があります。このクエリには、図のようにexpiration列を含めることもできます。

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句を追加します。この例では

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' 

Iは、現在の時刻として2016-02-03 08:00:00を用います。プロダクションシステムではNOW()を使用できます。

where句のsargableバージョンを使用することも賢明でしょう。

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

最後に、これは、設計の好みであるが、DATETIMEおよびUNIXタイムスタンプ列を混合することは少し奇妙です。

+1

@Arth、誤植のおかげで。 –

+0

こんにちは。 '2016-02-03 08:00:00 'ではなくunixtimeでどのようにテストできますか?基本的に私は1454775825をUNIXタイムスタンプの括弧の外側に追加しようとしましたが、エラーが発生しています。 – jason

+0

私はunix_time> = 1454775825-UNIX_TIMESTAMP(インターバルd.duration HOUR) – jason

2

は、カテゴリテーブルを作成し、移入:

  • カテゴリ - ID、hours_to_live

変更帳へ:

  • ブック - ID、名前、CATEGORY_ID、UNIX_TIME、time_data

と外国とカテゴリ表を参照キーcategory_id。

その後、あなたはJOINを使用すると、簡単なと望むものを達成することができます:すべての

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 
関連する問題