2012-02-23 11 views
1

月ごとに自動的にコンパイルされたレポートを作成する必要があります。このレポートは、2つのアプリ(Railsアプリ、アプリAとBと呼ぶ)の電話番号のユニークなカウントである必要があります。各アプリはPostgreSQLデータベースを持ち、電話番号はテーブルの列です。各アプリで一意の電話番号を取得するのは簡単ですが、それは単に「SELECT COUNT(DISTINCT phone_number)...」というクエリです。しかし、私は両方のアプリケーション(それに、アプリケーションAはテーブルに500kのレコードを持ち、アプリBは8kを持っています)でそれを行うためのシンプルで効率的な方法を考え出すことができません。私は両方のテーブルからすべての電話番号を取り出し、それらをまとめて重複を外さなければならないようです。問題は、メモリ内で扱うレコードが多すぎることです。レポートのアドバイス

誰かがこれを行う最善の方法について助言していますか?ここではいくつかの追加情報があります:

  • 両方のアプリケーションが同じサーバー
  • データベースサーバが
  • アプリは、異なるデータベース上にあるこのサーバー上にもある上にある
  • 生成/レポートを電子メールで送信することになるのcron私はアプリのいずれかであることが好ましく、Rubyでプログラミングのほとんどを行うことを好む仕事

答えて

1

SQLはその可能性がありますUNIONの方法がありますデータベース内で、2つのクエリ間のUNIONからDISTINCT値を引き出すことができます。

SELECT DISTINCT ON (phone_number) FROM 
(<subquery1> 
UNION ALL 
<subquey2> 
); 

これは非常に効率的なSQLクエリを提供します。これをRailsパースペクティブから実装し、両方のクエリから結果を取得する場合は、一意の検証を実行するのが最適です。

results1 = Table1.select('DISTINCT phone_number') 
results2 = Table2.select('DISTINCT phone_number') 

results = (results1 + results2).uniq! 

あなたが探していたものです。この後、約

+0

テーブルは異なるデータベースにあります。私はそれが簡単だったと思う:( – Austin

+0

私はそれを逃した、残念です。しかし、組み合わせとuniqのために、それはまだ動作するでしょうか? – xlash

+0

はい、それはうまくいくでしょう。 Rubyistのように、配列から重複を取り除く方法は、私が探している答えではありません。私は、_automatically_数値の総数を得るための最良の方法についてアドバイスが必要です。ファイルにダンプし、上でやっていることを別のスクリプトで行います。問題は500kレコードではあまりにも(遅すぎます) – Austin

-1

何:

Table1.count(:group => 'phone_number') 

はあなたのカウントのハッシュ、および値が得られます。 2つの結果を併合すると、答えが得られます。

+0

うわー。あなたは私の質問を完全に読まなかったと思います。 – Austin

+0

待って、あなたは上記のコメントをしたのと同じ人です。 WTF? – Austin

+0

このクエリは、上の500KBのレコードをすべてプルしてメモリに格納しなくても、上でコメントしたものとまったく同じです。これは、各dbについて計算された応答を返します。申し訳ありませんが、これはあなたを助けない場合、あなたはより明確になっている必要があります、他の人がそれを理解するように見える、または他の答えを持っていたでしょう。そして、あなたを助けようとしている誰かのためのダウンボートに感謝します。 – xlash

0

異なるデータラッパーにアクセスするには、Pgのバージョンに応じてdblinkおよび/または外部データラッパーを調べます。

これをPostgreSQLで完全に行うことができます。おそらく、2つのサーバーが重複しないレコードだけを返すようなことをしたいことに気をつけてください。ですから、FDWのを使用して、あなたが外国テーブルPNAを持っているし、セットアップPNBのようなものと想定されていると仮定すると:もちろん、これはのみ9.1で動作するはず

WITH pnas (phone_number) AS (
     SELECT phone_number 
     FROM pna 
    GROUP BY phone_number 
), 
pnbs (phone_number) as (
     SELECT phone_number 
     FROM pnb 
    GROUP BY phone_number 
), 
pns (phone_number) AS (
     SELECT phone_number 
     FROM pnas 
     UNION 
     SELECT phone_number 
     FROM pnbs 
) 
SELECT count(*) 
    FROM pns; 

をしていますが、データベース・リンクとPostgreSQL 8.4以降で似た何かができます。