2

私のタスクには、次のように作成された、常に更新される MySQL テーブルからの読み取りが含まれます。

CREATE TABLE mailing (
    addr VARCHAR(255) NOT NULL
);

(date_created フィールドなどはありません。恣意的ですが、これが与えられたものです)

このテーブルには数百万の電子メール アドレスが保持されると想定されており、毎日さらに追加されます。

このテーブルのすべてのドメインの過去 30 日間の毎日の成長を別のテーブルでカウントすることになっています。

CREATE TABLE domain_count (
    domain VARCHAR(255) NOT NULL PRIMARY KEY,
    total_count INT(11) NOT NULL DEFAULT 0,
    count_1 INT(11) NOT NULL DEFAULT 0,
    count_2 INT(11) NOT NULL DEFAULT 0,
    ...
    count_30 INT(11) NOT NULL DEFAULT 0
);

たとえば、1 日目にメーリング テーブルに 1 つのドメインからの 10 個のアドレスが含まれ、2 日目には 15 個のアドレスが含まれている場合、domain_count.count_1 = 10 および domain_count.count_2 = 5 が必要です。

そのためには、2 つのことを追跡する必要があります。1 つは、昨日の時点でのメーリング テーブル内のアドレスの総数です (したがって、2 日目はどこかに「10」を格納し、3 日目は「 15" がどこかに保存されています。これで、メーリング テーブルの 11 列目または 16 列目から検​​索を再開できます)。もう 1 つは最新の count_# 値です。これは、2 日目に count_2 に挿入する必要がある (そして 31 日目に count_1 にループバックする) 必要があるためです。

これらの値を別のファイルに簡単に保存できますが、そのようなことを行うのは本当に面倒です。これらの値をテーブル自体に関連付けることができる MySQL クエリはありますか?

4

2 に答える 2

1

あなたが説明するものに基準はありません。

SQL 標準の一部であるINFORMATION_SCHEMAあります。TABLESテーブルには列がありますが、これは現在の行数のみを示しています。TABLE_ROWS

あなたが説明したことを行うには、TABLES テーブルに基づいて別の従来のテーブルを作成し、TIMESTAMP 列を追加し、定期的に I_S テーブルから自分のテーブルに行をコピーします。

CREATE TABLE mydatabase.TABLES like INFORMATION_SCHEMA.TABLES;

ALTER TABLE mydatabase.TABLES ADD COLUMN updated_at TIMESTAMP;

/* once per day do the following: */    
INSERT INTO mydatabase.TABLES 
 SELECT *, NOW() FROM INFORMATION_SCHEMA.TABLES
 WHERE (table_schema, table_name) = ('mydatabase', 'mytable');
于 2013-07-19T22:07:39.153 に答える
1

特定の質問に答えるには、レポート用のデータのこのような集約と非正規化は、通常、DBMS ではなくデータ ウェアハウスでカバーされるものです。

問題を解決するために、より適切な構造は次のようになります。

CREATE TABLE `domain_count` (
    `domain` VARCHAR(255) NOT NULL PRIMARY KEY,
    `date` DATE NOT NULL,
    `count` INT(11) NOT NULL DEFAULT 0
);

データの集計をデータ自体から分離していますが、要件に対してクエリを実行する方が簡単な構造であることに気付くかもしれません。日付範囲/ BETWEEN演算子を使用して関心のある範囲を取得し、カウントを合計するか、GROUP BY を使用してドメイン、月などでグループ化できます。

于 2013-07-19T22:12:08.987 に答える