2

次の構造のDBテーブルがあります

id | dateCreated | numOfUsers

典型的な行が1の場合、 '2011-10-13 12:00:00'、4

私の行には過去4か月のデータが含まれていますが、かなりの数の日が欠落しているので、SQLを使用して欠落している日を知りたいのですが、このクエリを作成する方法について何かアイデアはありますか?

どういうわけか日数のリストを取得し、これらをデータベースの値と比較することで、これについて行っているのではないかと思います。

PHPまたは他のプログラミング言語を使用して複数のクエリを使用してこれを実行できることは知っていますが、可能であればデータベースレベルでこれを実行したいと思います。

前もって感謝します

4

6 に答える 6

2

PostgreSQLの場合、generate_series()関数を使用すると、「日付のリスト」をその場で生成するのは非常に簡単です。

with all_dates as (
   select cast((current_date - interval '4' month) as date) + i as the_date
   from generate_series(0, extract(day from current_date - (current_date - interval '4' month))::int) as i
) 
select ad.the_date, 
       y.id,
       y.numOfUsers
from all_dates t
  left join your_table y ON y.dateCreated = t.the_date; 
于 2011-10-17T14:47:03.970 に答える
1

日付テーブル、開始日と終了日、またはその他の形式の反復なしでそれを行う方法があります。

select DATEADD(day,1,left.dateCreated) as MissingDates
from dbo.MyTable as left
left outer join dbo.MyTable as right on DATEADD(day,1,left.dateCreated) = right.entry_time
where right.dateCreated is null

これにより、欠落している日付のスパンの開始日の列が返されます。次に、2番目の比較テーブルに1日を加算する代わりに、1を減算することにより、欠落している日付のスパンの最後の日付を返す別の列を作成することもできます。

于 2013-01-10T16:51:05.140 に答える
1

AFAIKは、すべてのデータベースでこれを機能させるためのステートメントは1つではありません... Oracleの場合、これを実行できます(MyTable欠落している日付をチェックするDBテーブルです)。

SELECT * FROM
(
SELECT A.MinD + MyList.L TheDate FROM
(SELECT  MIN (dateCreated ) MinD FROM MyTable) A,
(SELECT LEVEL - 1 L FROM DUAL CONNECT BY LEVEL <= (SELECT  Max (dateCreated ) - MIN (dateCreated ) + 1 FROM MyTable)) MyList
) D WHERE D.TheDate NOT IN ( SELECT dateCreated FROM MyTable T)
于 2011-10-17T14:24:35.737 に答える
1

MySQL を想定すると、変数を使用して、クエリ結果の各行の状態を保持できます。

SELECT @last := 'date you want to start with';

SELECT id, dateCreated, DATE_DIFF(dateCreated, @last) AS diff, @last := dateCreated
FROM yourtable
ORDER BY dateCreated ASC
HAVING diff > 1

これは実際の欠落した日数を返すわけではありませんが、欠落した日付の後の行と欠落した日数を返すことに注意してください。

于 2011-10-17T14:38:43.740 に答える
0

(私の意見では)簡単に最も効果的な方法は、あなたが言うように、すべての日付の表から始めることです。あなたはそれを自分で作成する必要があります、そしてあなたが作成したと仮定すると、ここにあなたのためのいくつかのオプションがあります...

SELECT
  *
FROM
  calendar    -- Your manually created table of dates
LEFT JOIN
  yourTable
    ON yourTable.DateField = calendar.DateField
WHERE
  yourTable.DateField IS NULL
  AND calendar.DateField >= @reportFirstDate
  AND calendar.DateField <= @reportLastdate

または...

SELECT
  *
FROM
  calendar    -- Your manually created table of dates
WHERE
  NOT EXISTS (SELECT * FROM yourTable WHERE yourTable.DateField = calendar.DateField)
  AND calendar.DateField >= @reportFirstDate
  AND calendar.DateField <= @reportLastdate

編集

この日付のリストを維持するのは「面倒」だと感じるかもしれませんが、このタイプのクエリにはパフォーマンス上の大きなメリットがあります。

日付テーブルを使用して、2つのインデックスを調べ、一方には存在するがもう一方には存在しないものを確認します。

日付テーブルがないと、はるかに複雑なアプローチになります...
1.テーブル内のすべてのレコードを取得します
2.テーブル内の次のレコードに自己結合します
3.連続した日付の場合は、それらを破棄します(ギャップのあるレコードを保持します)
4.ペアごとに、ループして欠落している日付を入力します5.
レポート期間の開始時に欠落している日付を処理します(ペアにDate1はありません)
6。レポート期間の終了時に欠落している日付を処理します(ペアにDate2はありません)

日付を使用して一時テーブルを作成する方が実際にはおそらく高速です。簡単な方法で作成してから、テーブルを再度削除してください。もしそうなら、なぜあなたは単に日付表を維持しないのですか?

  1. 100年のテーブルを持っているだけで、それを忘れてください
  2. すべてのコードで日付を最新に保つために、非常に簡単なコードを用意してください


確信が持てない場合は、さまざまなオプションを試して、インデックス付きの日付テーブルが他のオプションと比較してどれだけ高速であるかを自分で確認することをお勧めします。

(どれだけ短く、読みやすく、保守しやすいかは言うまでもありません)

于 2011-10-17T14:20:10.010 に答える