【问题标题】:Ranking users with weekly date period and listing all first ranked users使用每周日期对用户进行排名并列出所有排名第一的用户
【发布时间】:2015-10-20 13:27:33
【问题描述】:

我有一个名为 coupons 的表,其架构如下:

CREATE TABLE "public"."coupons" (
   "id" int4 NOT NULL,
    "suprise" bool NOT NULL DEFAULT false,
    "user_id" int4 NOT NULL,
    "start" timestamp NOT NULL,
    "win_price" numeric(8,2) NOT NULL DEFAULT 0::numeric,
    "fold" int4 NOT NULL DEFAULT 3,
    "pay" numeric(8,2) NOT NULL DEFAULT 0::numeric,
    "rate" numeric(8,2) NOT NULL DEFAULT 0::numeric,
    "win" varchar(255) NOT NULL DEFAULT 'H'::character varying COLLATE "default",
    "end" timestamp NOT NULL,
    "win_count" int4 NOT NULL DEFAULT 0,
    "match_count" int4 NOT NULL DEFAULT 0,
    "played" bool NOT NULL DEFAULT false,
    "created_at" timestamp NOT NULL,
    "updated_at" timestamp NOT NULL
)
WITH (OIDS=FALSE);

为了对win_price weekly 的用户进行排名,我编写了下面的查询以获得 27-07-2015 和 03-08-2015 之间的前 5 名:

SELECT ROW_NUMBER() OVER(ORDER BY sum(win_price) DESC) AS rnk,
       sum(win_price) AS win_price, user_id,
       min(created_at) min_create
FROM coupons
WHERE played = true AND win = 'Y'
AND created_at BETWEEN '27-07-2015' AND '03-08-2015'
GROUP BY user_id
ORDER BY rnk ASC
LIMIT 5;

我正在寻找一个新的查询,它每周但在给定的日期期间列出排名第一的用户。
即:2015 年 1 月 9 日至 2015 年 9 月 30 日期间:

rnk - win_price - user_id - min_create 1 - 1.52 - 1 - .........(第一周) 1 - 10.92 - 2 - .........(发送周) 1 - 11.23 - 1 - .........(第三周等)

【问题讨论】:

    标签: sql postgresql aggregate-functions greatest-n-per-group window-functions


    【解决方案1】:
    SELECT *
    FROM  (
       SELECT date_trunc('week', created_at) AS week
            , rank() OVER (PARTITION BY date_trunc('week', created_at)
                           ORDER BY sum(win_price) DESC NULLS LAST) AS rnk
            , sum(win_price) AS win_price
            , user_id
            , min(created_at) min_create
       FROM   coupons
       WHERE  played = true
       AND    win = 'Y' AND created_at BETWEEN '27-07-2015' AND '03-08-2015'
       GROUP  BY 1, 4  -- reference to 1st & 4th column
       ) sub
    WHERE  rnk = 1
    ORDER  BY week;
    

    这将返回每周的获胜用户 - 拥有最多 sum(win_price) 的用户。

    请注意,我使用的是 rank() instead of row_number(),因为您没有为每周的多个获胜者定义决胜局。

    还要注意排序子句DESC NULLS LAST:这可以防止 NULL 值首先排序(如果你应该有 NULL):

    星期由起始时间戳表示,您可以使用to_char() 任意设置格式。

    查询的关键元素:您可以使用窗口函数而不是聚合函数。详情:

    考虑SELECT 查询中的事件顺序:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-09-29
      • 2019-10-23
      • 2014-01-14
      • 2014-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多