2012-02-23 2 views
1

Je dois créer un rapport qui est compilé automatiquement tous les mois. Le rapport doit juste être le nombre unique de numéros de téléphone à travers 2 applications (applications Rails, appelez-les app A et B). Chaque application a une base de données PostgreSQL et les numéros de téléphone sont des colonnes dans une table. Obtenir le nombre de numéros de téléphone uniques dans chaque application est facile, c'est juste une requête 'SELECT COUNT (DISTINCT phone_number) ...'. Cependant, je ne peux pas trouver un moyen simple/efficace de le faire à travers les deux applications (En outre, l'application A a 500k enregistrements dans la table et l'application B a 8k). Il semble que je vais devoir sortir tous les numéros de téléphone des deux tables, les assembler et lancer des doublons. Le problème c'est qu'il y a trop de dossiers à traiter en mémoire.Conseil sur un rapport

Quelqu'un a des conseils sur la meilleure façon de faire cela? Voici quelques informations supplémentaires:

  • Les deux applications sont sur le même serveur
  • Le serveur de base de données est également sur ce serveur
  • Les applications sont sur différentes bases de données
  • Génération/emailing le rapport sera un Cron emploi
  • Je préfère faire la plupart de la programmation en ruby, de préférence dans l'une des applications

Répondre

1

SQL a une méthode qui pourrait UNION soyez ce que vous recherchez ... Dans la base de données, vous seriez en mesure d'extraire les valeurs DISTINCT d'une UNION entre vos 2 requêtes.

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

Cela vous donnerait une requête SQL très efficace. Maintenant, si vous voulez implémenter cela à partir d'une perspective Rails, obtenir les résultats des deux requêtes, puis effectuer une validation unique serait la meilleure.

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

results = (results1 + results2).uniq! 

Espérons que c'est ce que vous cherchiez!

+0

Les tables se trouvent dans différentes bases de données. J'aurais aimé que ce soit si simple :( – Austin

+0

J'ai regretté cela, désolé, mais pour la combinaison et uniq !, ça marcherait encore, n'est-ce pas? – xlash

+0

Oui, ça marcherait, mais ce n'est pas mon problème. Rubyist, donc la façon de lancer des doublons dans un tableau n'est pas la réponse que je recherche, j'ai besoin de conseils sur la meilleure façon d'obtenir automatiquement le nombre unique de nombres. , le vider dans un fichier, et avoir un autre script faire ce que vous faites ci-dessus.Le problème est avec 500k enregistrements c'est trop (trop lent) – Austin

-1

Qu'en est-ce alors:

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

vous donnera un hachage du comte, et la valeur. Fusionner les 2 résultats ensemble, vous avez votre réponse.

+0

Wow. Je suppose que vous n'avez pas complètement lu ma question. – Austin

+0

Attendez, vous êtes le même gars qui a commenté ci-dessus. WTF? – Austin

+0

Cette requête fait exactement ce que vous avez commenté ci-dessus, sur la base de données, sans que vous ayez à tirer tous les 500k enregistrements et à les mettre en mémoire. Il vous renvoie une réponse calculée pour chaque db. Désolé si cela ne vous aide pas, vous auriez dû être plus clair, on dirait que personne d'autre ne le comprend, sinon vous auriez eu d'autres réponses. Et merci pour le downvote pour quelqu'un qui essaie de vous aider. – xlash

0

Pour accéder aux différents wrappers de données, examinez les dblink et/ou les wrappers de données étrangers en fonction de votre version Pg.

Ensuite, vous pouvez le faire entièrement dans PostgreSQL. Gardez à l'esprit que vous voulez probablement faire quelque chose comme vous assurer que les deux serveurs ne retournent que des enregistrements non dupliqués. Donc, en supposant que vous utilisez est vous fdw et en supposant avez des tables étrangères pna et pnb mis en place, quelque chose comme:

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; 

Bien sûr, devrait fonctionner avec 9.1 seulement, mais vous pouvez faire quelque chose de similaire avec dblink et PostgreSQL 8.4 et version supérieure .