【问题标题】:PSQL Head to Head Records by Date按日期排列的 PSQL 头对头记录
【发布时间】:2021-04-23 13:16:32
【问题描述】:

我正在寻找一种方法来更新联系人的统计信息(与其他联系人相比)。我希望预期的数据表包含与之配对的每个联系人的历史结果。

完成的数据

id date contact1 contact2 contact1_orders contact2_orders
1 2021-04-01 bob joe 2 1
2 2021-04-02 bob joe 1 2
3 2021-04-03 jim tim 2 1
4 2021-04-04 tim jim 1 2
5 2021-04-05 joe bob 1 2
6 2021-04-06 joe bob 1 2

即将到来的日期的预期数据 - 分别更新每个联系人与不同联系人的头对头结果。

id date contact1 contact2 contact1_h2h contact2_h2h
1 2021-04-01 bob joe 0 0
2 2021-04-02 bob joe 1 0
3 2021-04-03 jim tim 0 0
4 2021-04-04 tim jim 0 1
5 2021-04-05 joe bob 2 1
6 2021-04-06 joe bob 3 1

例如,Bob 和 Joe 在第 7 行之前配对了 4 次。Bob 比 Joe 订购了 3 次以上,而 Joe 比 Bob 订购了 1 次以上。

contact1_orders 是 contact1 在给定日期(或行 ID)下的订单数。

contact2_orders 是 contact2 在给定日期(或行 ID)下的订单数。

contact1_h2h 是之前contact1 与contact2 配对的记录数,其中contact1 下的订单多于contact2。

contact2_h2h 是contact2 与contact2 下的订单多于contact1 的联系人配对的先前记录数。

我正在寻找一个查询来更新预期数据表中的contact1_h2h 和contact2_h2h,其中联系人订购的天数超过了他们所关联的联系人。

【问题讨论】:

  • 有两列,你只解释了一个。此外,我不遵循解释。它似乎不适用于 jim/tim。
  • @GordonLinoff 我为列添加了解释。请让我知道这是否有帮助或您需要进一步的解释。
  • 。 .我仍然不认为你的数字是正确的。 Joe 输给了 Bob,但您增加了错误的列。此外,有些行包含逻辑中的行,有些则不包含。

标签: sql postgresql


【解决方案1】:

我想我明白你想要什么。您需要根据值之间的比较得出每个人“获胜”的次数。

以下查询将结果以规范格式(按字母顺序)来确定计数:

select t.*,
       count(*) filter (where is_c1_win) over (partition by c1, c2 order by date)  as c1_h2h,
       count(*) filter (where is_c2_win) over (partition by c1, c2 order by date) as c2_h2h
from (select t.*, least(contact1, contact2) as c1,
             greatest(contact1, contact2) as c2,
             (contact1_orders > contact2_orders and contact1 < contact2 or
              contact2_orders > contact1_orders and contact2 < contact1
             ) as is_c1_win,
             (contact1_orders > contact2_orders and contact1 > contact2 or
              contact2_orders > contact1_orders and contact2 > contact1
             ) as is_c2_win
      from t
     ) t;

然后您可以将这些重新分配回联系人的原始顺序:

with h2h as (
      select t.*,
             count(*) filter (where is_c1_win) over (partition by c1, c2 order by date)  as c1_h2h,
             count(*) filter (where is_c2_win) over (partition by c1, c2 order by date) as c2_h2h
      from (select t.*, least(contact1, contact2) as c1,
                   greatest(contact1, contact2) as c2,
                   (contact1_orders > contact2_orders and contact1 < contact2 or
                    contact2_orders > contact1_orders and contact2 < contact1
                   ) as is_c1_win,
                   (contact1_orders > contact2_orders and contact1 > contact2 or
                    contact2_orders > contact1_orders and contact2 > contact1
                   ) as is_c2_win
            from t
           ) t
      )
select h2h.*,
       (case when contact1 < contact2 then c1_h2h else c2_h2h end) as contact1_h2h,
       (case when contact1 < contact2 then c2_h2h else c1_h2h end) as contact2_h2h
from h2h
order by id;

结果与您的结果不同,但这些似乎是正确的。

Here 是一个 dbfiddle。

【讨论】:

  • 非常感谢您的帮助,戈登!我已经为此无休止地工作了一个多星期。我真的很接近,但由于某种原因无法弄清楚最后一行。我真的很感谢您的支持,并会找到一种方式来支付它。
猜你喜欢
  • 1970-01-01
  • 2017-05-26
  • 1970-01-01
  • 2021-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多