簡體   English   中英

Postgres 使用不同的 ID 計算平均值,值也不同

[英]Postgres calculate average using distinct IDs‚ values also distinct

我有一個 postgres 查詢,它應該根據一組值計算平均值。 這組值應基於 DISTINCT ID。

查詢如下:

#{context.answers_base}
SELECT
    stores.name as store_name,
    answers_base.question_name as question_name,
    answers_base.question_id as question_id,
    (sum(answers_base.answer_value) / NULLIF(count(answers_base.answer_id),0)) as score, # <--- this line is calculating wrong
    sum(answers_base.answer_value) as score_sum,
    count(answers_base.answer_id) as question_answer_count,
    count(DISTINCT answers_base.answer_id) as answer_count
FROM answers_base
  INNER JOIN stores ON stores.id = answers_base.store_id
WHERE answers_base.answer_value IS NOT NULL AND answers_base.question_type_id = :question_type_id
      AND answers_base.scale = TRUE
#{context.filter_answers}
GROUP BY stores.name, answers_base.question_name, answers_base.question_id, answers_base.sort_order
ORDER BY stores.name, answers_base.sort_order

問題是,在指示的行(sum(answers_base.answer_value) / NULLIF(count(answers_base.answer_id),0))中,某些值被多次計算。

部分解決方案是根據 ID 使其成為 DISTINCT,如下所示: (sum(answers_base.answer_value) / NULLIF(count(DISTINCT answers_base.answer_id),0))

這將導致除以正確數字的平均值,但這里它除以的總和仍然是錯誤的。

執行以下操作 (make sum() DISTINCT) 不起作用,因為值不是唯一的。 這些值是 0 / 25 / 50 / 75 / 100,因此不同的 ID 可能包含“相同”的值。 (sum(DISTINCT answers_base.answer_value) / NULLIF(count(DISTINCT answers_base.answer_id),0))

我將如何 go 使這項工作?

以下是表結構的簡化版本。

表格答案

ID 回答日期
1個 2022 年 2 月 1 日
2個 2022 年 3 月 2 日
3個 2022 年 3 月 13 日
4個 2022 年 3 月 21 日

AnswerRow

ID answer_id 答案值
1個 1個 25
2個 1個 50
3個 1個 50
4個 2個 75
5個 2個 100
6個 2個 0
7 3個 25
8個 4個 25
9 4個 100
10 4個 50

答案 1' answer_rows : 25 + 50 + 50 -> average = 125 / 3

答案 2' answer_rows : 75 + 100 + 0 -> average = 175 / 3

答案 3' answer_rows : 25 -> average = 25 / 1

答案 4' answer_rows :25 + 100 + 50 -> average = 175 / 3

由於某種原因,我們在計算中得到了重復的 answer_rows。

問題的例子; 對於answer_id=1我們在計算中有以下 answer_rows,給我們一個不同的平均值:

ID answer_id 答案值
1個 1個 25
2個 1個 50
3個 1個 50
3個 1個 50
3個 1個 50
3個 1個 50

結果: 25 + 50 + 50 + 50 + 50 + 50 -> 275 / 6期望結果: 25 + 50 + 50 -> 125 / 3

使 answer_row_id 不同(見帖子開頭)使我有可能得到: 25 + 50 + 50 + **50 + 50 + 50** -> 275 / **3**但不是25 + 50 + 50 -> 275 / 3

我想要實現的是根據其 ID 明確選擇answer_row的計算,並且這些answer_rows 將在計算average -> x / y中用於計算xy

answers_base 如下(簡化):

WITH answers_base as (
  SELECT
      answers.id as answer_id,
      answers.store_id as store_id,
      answer_rows.id as answer_row_id,
      question_options.answer_value as answer_value
  FROM answers
      INNER JOIN answer_rows ON answers.id = answer_rows.answer_id
      INNER JOIN stores ON stores.id = answers.store_id
  WHERE answers.status = 0
)

我認為這最好用window function解決。 類似的東西

SELECT
   ROW_NUMBER() OVER (PARTITION BY answer_rows.id ORDER BY answer_rows.created_at DESC) AS duplicate_answers
   ...
WHERE
   answer_rows.duplicate_answers = 1

這將過濾掉具有相同id的多行,並且只保留一個條目。 (我選擇了“first by created_at ”,但您可以將其更改為最適合您的邏輯。)

這種方法的一個好處是它使邏輯背后的基本原理清晰、包含和可重用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM