1

データを非正規化しました(日付が年、月、日、時間の列に分割されています)が、特定の日付より前のすべてをクエリする方法がわかりません。

これは動作しません:

SELECT * 
FROM  `impression_stat_hour` 
WHERE doneforday =0
AND (
    YEAR <=2011
    AND MONTH <=6
    AND DAY <=30
    AND HOUR <=1
)

これは、実際にはすべてのレコードを必要に応じて「グループ化」するわけではないため、(たとえば)常に0時間から1時間までの日付になります。

4

2 に答える 2

1
SELECT ...
WHERE
    YEAR < 2011
    OR (YEAR = 2011 AND MONTH < 6)
    OR (YEAR = 2011 AND MONTH = 6 AND DAY < 30)
    OR (YEAR = 2011 AND MONTH = 6 AND DAY = 30 AND HOUR <= 1)

または:

SELECT ...
WHERE STR_TO_DATE(CONCAT(year,'-',month,'-',day,' ',hour,':00:00')) <= '2011-06-30 01:00:00';

後者はおそらくはるかに低速です(さまざまな日付列でインデックスを使用できないためです。また、アクセスできるMySQLの唯一の(古代の)バージョンがSTR_TO_DATE()をサポートしていないため、テストされていません。

于 2011-06-30T23:58:05.213 に答える
1
  1. 同点を処理するには、条件をより複雑にする必要があります。

    AND (YEAR < 2011 OR (YEAR = 2011 
      AND (MONTH < 6 OR (MONTH = 6 
        AND (DAY < 30 OR (DAY = 30 AND HOUR <= 1))))))
    
  2. DATETIME列を組み合わせて値に戻し、それを特定の日時リテラルと比較すると、おそらく読みやすくなります。

    AND (STR_TO_DATE(CONCAT(YEAR,'-', MONTH,'-', DAY, ' ', HOUR), 
     '%Y-%m-%d %h') < '2011-06-30 02:00')
    
  3. DATETIME個別の日時コンポーネントを持つ列の値と同じ値に基づいて実際の列を追加して保存することもできます。これにより、より効率的なルックアップのために日時列にインデックスを付けることができます。

    AND (complete_date < '2011-06-30 02:00')
    

@Flimzyからの回答を含め、MySQL5.5でこれをテストしました。インデックスを使用できるのは、冗長な列を持つ上記の方法3だけです。

于 2011-07-01T00:01:06.933 に答える