Essayer de créer une requête à exécuter sur ma table "cdr" où je peux la nourrir d'environ 200 numéros de téléphone et la comparer à la colonne "src" de la table et renvoyer le dernier enregistrement basé sur la "date d'appel "colonne.
Exemple de tableau:
SELECT * FROM cdr WHERE calldate = (SELECT max(calldate) FROM cdr WHERE src LIKE '5551234');
Je dois donc pouvoir alimenter ma requête sql src #s car ma base de données contient beaucoup d'enregistrements, je m'en fiche à propos de ie je veux seulement trouver les derniers appels faits par #s 5551234, 5551898 et 5551887 mais ignorer tous les autres. Je dois également m'assurer que la disposition sur les enregistrements renvoyés est également "RÉPONSE".
Donc, ce que j'ai essayé jusqu'à présent sans même filtrer les réponses ou non était la suivante:
SELECT src, calldate FROM cdr WHERE src IN (5551234, 5551898, 5551887) GROUP by src;
Cela renvoie 3 enregistrements mais ils ne semblent pas être les plus récents. Par exemple, 5551234 date du 18/11/2014, ce qui n'est pas l'enregistrement le plus récent. J'ai confirmé cela en exécutant simplement la requête suivante:
+------------------+---------+-------------+ | calldate | src | disposition | +------------------+---------+-------------+ | 10/23/2019 11:32 | 5551234 | ANSWERED | | 10/23/2019 11:32 | 5551245 | NO ANSWER | | 10/23/2019 11:28 | 5551234 | ANSWERED | | 10/23/2019 11:21 | 5551898 | ANSWERED | | 10/23/2019 11:20 | 5551245 | NO ANSWER | | 10/23/2019 11:20 | 5551887 | NO ANSWER | | 10/23/2019 11:18 | 5551898 | NO ANSWER | | 10/23/2019 11:18 | 5551887 | NO ANSWER | | 10/23/2019 11:17 | 5551234 | NO ANSWER | | 10/23/2019 11:14 | 5551898 | ANSWERED | | 10/23/2019 11:09 | 5551887 | ANSWERED | +------------------+---------+-------------+
l'enregistrement renvoyé était daté du 24/06/2019.
Je m'attendais à ce que les enregistrements les plus récents soient renvoyés , mais il semble renvoyer un enregistrement aléatoire (le même à chaque fois mais ce n'est ni le plus récent ni le plus ancien enregistrement disponible).
Pour y penser logiquement, j'ai essentiellement besoin de tirer max (calldate) pour chaque entrée IN je l'alimente par rapport à l'extraction de la date d'appel maximale des enregistrements retournés pour les entrées IN, ce qui entraîne le retour d'un seul enregistrement. At wits se termine ici et ne peut pas penser clairement.
Exécuter cette base de données sur mysql d'ailleurs.
3 Réponses :
J'utiliserais une sous-requête corrélée pour filtrer sur la dernière date par src . Cette approche évite d'utiliser l'agrégation et a généralement de meilleures performances, en particulier avec un index sur (src, calldate) .
SELECT calldate, src, disposition
FROM (
SELECT c.*, RANK() OVER(PARTITION BY src ORDER BY calldate DESC) rn
FROM cdr c
WHERE scr IN (5551234, 5551898, 5551887)
) x
WHERE rn = 1
Une autre solution typique consiste à utiliser la fonction window RANK () :
SELECT c.*
FROM cdr c
WHERE
c.src IN (5551234, 5551898, 5551887)
AND calldate = (
SELECT calldate
FROM cdr c1
WHERE c1.sr = c.src
ORDER BY c1.calldate DESC
LIMIT 1
)
Vous avez une partie de la réponse dans votre dernière requête, je ferais quelque chose comme
SELECT src, MAX(calldate) AS last_call FROM cdr WHERE src IN (5551234, 5551898, 5551887) -- AND disposition = 'ANSWERED' GROUP by src;
Merci! Une idée de pourquoi l'ajout de AS last_call lui permet de renvoyer les derniers enregistrements par rapport à la façon dont je l'avais avant? Plus simplement vouloir savoir exactement ce qui se passe.
Donner au résultat l'alias "last_call" est juste pour faciliter la lisibilité. Sinon, le nom de la colonne de résultat serait "MAX (date d'appel)". Normalement, une requête avec "MAX" ou "MIN" ou "COUNT" (par exemple) entraînera la requête pour renvoyer un seul résultat, selon celui qui répond aux critères. Cependant, lorsque nous ajoutons le "GROUP BY" en bas, nous disons à la requête que nous voulons le MAX pour chaque élément DISTINCT GROUP BY. Votre première requête saisissait simplement la première date d'appel qui apparaîtrait pour chaque src distinct, mais en ajoutant le mot-clé MAX, il trouve le max au lieu du premier qu'il trouve.
Si vous n'avez que ces trois colonnes, alors group by fonctionne. Sinon, je recommanderais:
select c.*
from cdr c
where c.src in (5551234, 5551898, 5551887) and
c.calldate = (select max(c2.calldate)
from cdr c2
where c2.src = c.src
);
Pour des performances optimales, vous voulez un index sur cd (src, calldate) . Avec un tel index, je m'attendrais à ce que ce soit plus rapide qu'une approche group by .