2009-05-27 8 views
1

Salut tout le monde, je suis de retour et j'attends avec impatience votre plus grand éclat. J'ai deux tables:Requête MySQL compliquée pour la file d'attente de la newsletter

  1. bulletins - chaque ligne contient un 'id', 'sujet', 'corps' & 'de' têtes pour un email
  2. newsletter_queue - chaque ligne contient un 'id', ' email » adresse, « date » ajouté à la file d'attente et le « newsletterid »

Mon objectif est de développer une requête MySQL qui peut tirer une quantité x de lignes de « newsletter_queue », puis de les regrouper par leur « newsletterid » en en utilisant GROUP_CONCAT (ou tout ce qui fonctionne) pour mettre tous les emails dans une chaîne séparée par un caractère que je vais analyser avec PHP. La raison pour laquelle je voudrais les avoir ensemble est parce que la bibliothèque d'expéditeur que j'utilise (swiftmailer) accepte un tableau avec des email pour des email de lot. Aussi, si possible, il serait très utile de joindre les deux tables ensemble, évitant ainsi une deuxième requête.

Voici ce que j'ai jusqu'à présent:

SELECT GROUP_CONCAT(email ORDER BY date ASC SEPARATOR '|'), newsletterid, date 
FROM newsletter_queue 
WHERE status='0' 
GROUP BY newsletterid 
LIMIT 125 

Mon problème est que la limite de 125 est appliquée aux lignes déjà chaînés, rendant inutile en raison du fait que je suis en train de limiter la quantité du nombre total de courriels envoyés à la fois, pas de bulletins uniques. Si quelqu'un pouvait me guider dans la bonne direction, je serais très reconnaissant. Si vous finissez par écrire l'exemple, c'est génial aussi.

+0

Y at-il une bonne raison de concaténer les e-mails dans SQL? Surtout que le post-traitement avec PHP est nécessaire de toute façon. Extraire une bouillie non structurée de la chaîne d'une base de données est sous-optimale, à mon humble avis. – Tomalak

+0

@Tomalak, eh bien, ça me sauve d'itéter à travers une boucle while() pour les ajouter dans un tableau. La façon dont il est configuré maintenant, la boucle while() ne boucle qu'une fois pour chaque newsletter unique, j'utilise explode() pour transformer les emails en un tableau, et la fonction batchSend() que j'utilise les envoie tous en même temps, plutôt qu'ouvrir une connexion smtp pour chaque adresse email. Recommanderiez-vous une autre méthode? – bloudermilk

Répondre

3
SELECT GROUP_CONCAT(email ORDER BY date ASC SEPARATOR '|'), newsletterid, date 
FROM 
    (SELECT email, newsletterid, date 
    FROM newsletter_queue 
    WHERE status="0" 
    ORDER BY date ASC 
    LIMIT 125) as Unsent 
GROUP BY newsletterid 

Cela applique la limite à la requête interne, avant l'exécution de l'instruction group by. Peu importe que l'instruction group by soit dans la requête externe car un groupe by aura besoin d'une table temporaire et d'un tri de toute façon. Si vous avez besoin d'une sorte de tri du résultat concaténé, vous pouvez simplement l'appliquer à la requête externe, par exemple en appliquant max ou min à date et en l'ordonnant.

+0

Merci pour la faute de frappe Lieven – PatrikAkerstrand

+0

@Machine, pas de problème. En ce qui concerne votre solution, ne limite-t-elle pas le nombre d'enregistrements de newsletter_queue à 125? J'étais sous l'impression que l'OP voulait que tous les enregistrements de newsletter_queue soient traités. –

+0

A travaillé merveilleusement et ajouter une jointure était très facile! – bloudermilk

0

Une idée géniale mais cela fonctionne-t-il?

SELECT GROUP_CONCAT(email ORDER BY date ASC SEPARATOR '|'), newsletterid, date 
FROM newsletter_queue 
WHERE status='0' 
GROUP BY newsletterid, ID MOD 125 

Je soupçonne que le montant maximum de dans adresses e-mail un enregistrement pour être 125.
Malheureusement, le montant est pas exact 125. Il pourrait se situer entre 1 et 125.

+0

>> ou quel que soit mod est dans mysql: MOD (N, M); N% M; N MOD M –

+0

@Salman A, merci. J'ai mis à jour la réponse –

2

Cela devrait aussi faire ce que vous voulez:

SELECT substring_index(GROUP_CONCAT(email ORDER BY date ASC SEPARATOR '|'),'|',125), newsletterid, date 
FROM newsletter_queue 
WHERE status='0' 
GROUP BY newsletterid 
Questions connexes