Je cherche de l'aide pour utiliser sum () dans ma requête SQL:
SELECT links.id,
count(DISTINCT stats.id) as clicks,
count(DISTINCT conversions.id) as conversions,
sum(conversions.value) as conversion_value
FROM links
LEFT OUTER JOIN stats ON links.id = stats.parent_id
LEFT OUTER JOIN conversions ON links.id = conversions.link_id
GROUP BY links.id
ORDER BY links.created desc;
J'utilise DISTINCT
parce que je fais "group by" et cela garantit que la même ligne n'est pas comptée plus d'une fois.
Le problème est que SUM (conversions.value) compte la "valeur" pour chaque ligne plus d'une fois (en raison du regroupement par)
Je veux essentiellement faire SUM(conversions.value)
pour chaque conversion DISTINCT.id.
Est-ce possible?
Je peux me tromper mais d'après ce que je comprends
Ainsi, pour chaque conversions.id, vous avez au plus un links.id impacté.
Votre demande, c'est un peu comme faire le produit cartésien de 2 sets:
[clicks]
SELECT *
FROM links
LEFT OUTER JOIN stats ON links.id = stats.parent_id
[conversions]
SELECT *
FROM links
LEFT OUTER JOIN conversions ON links.id = conversions.link_id
et pour chaque lien, vous obtenez des lignes sizeof ([clics]) x sizeof ([conversions])
Comme vous l'avez noté, le nombre de conversions uniques dans votre demande peut être obtenu via un
count(distinct conversions.id) = sizeof([conversions])
ce distinct parvient à supprimer toutes les lignes [clics] dans le produit cartésien
mais clairement
sum(conversions.value) = sum([conversions].value) * sizeof([clicks])
Dans votre cas, depuis
count(*) = sizeof([clicks]) x sizeof([conversions])
count(*) = sizeof([clicks]) x count(distinct conversions.id)
vous avez
sizeof([clicks]) = count(*)/count(distinct conversions.id)
donc je testerais votre demande avec
SELECT links.id,
count(DISTINCT stats.id) as clicks,
count(DISTINCT conversions.id) as conversions,
sum(conversions.value)*count(DISTINCT conversions.id)/count(*) as conversion_value
FROM links
LEFT OUTER JOIN stats ON links.id = stats.parent_id
LEFT OUTER JOIN conversions ON links.id = conversions.link_id
GROUP BY links.id
ORDER BY links.created desc;
Tiens moi au courant ! Jérôme
La solution Jeromes est en fait fausse et peut produire des résultats incorrects !!
sum(conversions.value)*count(DISTINCT conversions.id)/count(*) as conversion_value
supposons le tableau suivant
conversions
id value
1 5
1 5
1 5
2 2
3 1
la somme de valeur correcte pour des identifiants distincts serait de 8. La formule de Jérôme produit:
sum(conversions.value) = 18
count(distinct conversions.id) = 3
count(*) = 5
18*3/5 = 9.6 != 8
Pour une explication de la raison pour laquelle vous voyez des chiffres incorrects, lire ceci.
Je pense que Jerome a une idée de ce qui cause votre erreur. La requête de Bryson fonctionnerait, bien que cette sous-requête dans SELECT puisse être inefficace.
Utilisez la requête suivante:
SELECT links.id
, (
SELECT COUNT(*)
FROM stats
WHERE links.id = stats.parent_id
) AS clicks
, conversions.conversions
, conversions.conversion_value
FROM links
LEFT JOIN (
SELECT link_id
, COUNT(id) AS conversions
, SUM(conversions.value) AS conversion_value
FROM conversions
GROUP BY link_id
) AS conversions ON links.id = conversions.link_id
ORDER BY links.created DESC
J'utilise une sous-requête pour ce faire. Il élimine les problèmes de regroupement. La requête serait donc quelque chose comme:
SELECT COUNT(DISTINCT conversions.id)
...
(SELECT SUM(conversions.value) FROM ....) AS Vals
Que diriez-vous quelque chose comme ça:
select l.id, count(s.id) clicks, count(c.id) clicks, sum(c.value) conversion_value
from (SELECT l.id id, l.created created,
s.id clicks,
c.id conversions,
max(c.value) conversion_value
FROM links l LEFT
JOIN stats s ON l.id = s.parent_id LEFT
JOIN conversions c ON l.id = c.link_id
GROUP BY l.id, l.created, s.id, c.id) t
order by t.created
Cela fera l'affaire, divisez simplement la somme avec le nombre d'ID de conversation qui sont en double.
SELECT a.id,
a.clicks,
SUM(a.conversion_value/a.conversions) AS conversion_value,
a.conversions
FROM (SELECT links.id,
COUNT(DISTINCT stats.id) AS clicks,
COUNT(conversions.id) AS conversions,
SUM(conversions.value) AS conversion_value
FROM links
LEFT OUTER JOIN stats ON links.id = stats.parent_id
LEFT OUTER JOIN conversions ON links.id = conversions.link_id
GROUP BY conversions.id,links.id
ORDER BY links.created DESC) AS a
GROUP BY a.id