web-dev-qa-db-ja.com

個別の行のMYSQL sum()

SQLクエリでsum()を使用するヘルプを探しています。

_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;
_

「グループ化」を行っているため、DISTINCTを使用します。これにより、同じ行が複数回カウントされないことが保証されます。

問題は、SUM(conversions.value)が各行の「値」を複数回カウントすることです(グループ化のため)

基本的に、各DISTINCT conversions.idに対してSUM(conversions.value)を実行します。

それは可能ですか?

41
makeee

私は間違っているかもしれませんが、私が理解していることから

  • conversions.id主キーテーブルのconversions
  • stats.idはテーブルの主キーstats

したがって、conversions.idごとに、最大で1つのlinks.idが影響を受けます。

あなたが要求するのは、2セットのデカルト積を行うことに少し似ています:

[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 

各リンクについて、sizeof([clicks])x sizeof([conversions])行を取得します

ご指摘のとおり、リクエスト内のユニークコンバージョンの数は、

count(distinct conversions.id) = sizeof([conversions])

これにより、デカルト積の[クリック]行がすべて削除されます。

しかし、明らかに

sum(conversions.value) = sum([conversions].value) * sizeof([clicks])

あなたの場合、

count(*) = sizeof([clicks]) x sizeof([conversions])
count(*) = sizeof([clicks]) x count(distinct conversions.id)

あなたが持っている

sizeof([clicks]) = count(*)/count(distinct conversions.id)

だから私はあなたの要求をテストします

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;

投稿してください!ジェローム

73
Jerome WAGNER

Jeromesソリューションは実際には間違っており、誤った結果を生成する可能性があります!!

sum(conversions.value)*count(DISTINCT conversions.id)/count(*) as conversion_value

次の表を想定してみましょう

conversions
id value
1 5
1 5
1 5
2 2
3 1

個別のIDの値の正しい合計は8になります。ジェロームの式は以下を生成します

sum(conversions.value) = 18
count(distinct conversions.id) = 3
count(*) = 5
18*3/5 = 9.6 != 8
11

間違った数字が表示される理由の説明については、こちらをお読みください

Jeromeには、エラーの原因を把握していると思います。 Brysonのクエリは機能しますが、SELECTにサブクエリを含めることは非効率的です。

7
TehShrike

次のクエリを使用します。

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
4
Bryson

これを行うには、サブクエリを使用します。グループ化の問題を排除します。したがって、クエリは次のようになります。

SELECT COUNT(DISTINCT conversions.id)
...
     (SELECT SUM(conversions.value) FROM ....) AS Vals
3
Dave

このようなものはどうですか:

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  
2
Quesi

これはトリックを行い、重複した会話IDの数で合計を除算します。

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
1
Dipu Raj