为排行榜

时间:2015-06-16 00:45:29

标签: database postgresql

大家好我有一个似乎是一个简单的问题(至少在我脑海中),但我还没有找到一个可靠的方法来解决这个问题。

以下是我正在运行的查询,以获取我的应用的当前排行榜。我想要回来的还有项目位置/等级以及像我一样胜利,失败等属性。

SELECT "Item"."id",

(SELECT COUNT("Votes"."id") FROM "Votes" WHERE type = 'up' AND "Votes"."LunchId" = "Item"."id" AND "Votes"."scope" = 'regional')::INTEGER AS "wins", 
(SELECT COUNT("Votes"."id") FROM "Votes" WHERE type = 'down' AND "Votes"."LunchId" = "Item"."id" AND "Votes"."scope" = 'regional')::INTEGER AS "loses", 
(SELECT COALESCE((SELECT round( 100.0*sum( CASE WHEN "Votes"."type" = 'up' AND "Votes"."scope" = 'regional' THEN 1 ELSE 0 END )/sum(1), 3) FROM "Votes" WHERE "Votes"."LunchId" = "Item"."id" AND "Votes"."scope" = 'regional' ),0))::DECIMAL AS "percent", 
(SELECT count(*) FROM "Lunches" WHERE date("Lunches"."createdAt") = (SELECT date("createdAt") FROM "Lunches" WHERE "Lunches"."id" = "Item"."id") AND "Lunches"."region" = "Item"."region")::INTEGER AS "total"

FROM "Lunches" AS "Item" 

WHERE "Item"."region" = 'east' 
AND "Item"."createdAt" BETWEEN '2015-06-15T011:30:00-04:00' AND '2015-06-15T16:00:00-04:00' 
ORDER BY "percent" DESC, "wins" DESC, "Item"."createdAt" ASC;

我想要这样格式化的原因是我希望能够通过一个AND“Item”轻松地请求它。“id”= 40也可以快速找到它的等级。这可行吗?

谢谢!

------更新-------

这是我的表架构:

CREATE TABLE "Lunches" (
    id integer NOT NULL,
    region "enum_Lunches_region" NOT NULL,
    timezone character varying(255),
    description character varying(255),
    "regionWinner" boolean DEFAULT false,
    "nationalWinner" boolean DEFAULT false,
    type character varying(30) DEFAULT 'restaurant'::character varying,
    "createdAt" timestamp with time zone NOT NULL,
    "updatedAt" timestamp with time zone NOT NULL,
    "LocationId" integer,
    "UserId" integer,
    "PhotoId" integer
);

CREATE TABLE "Votes" (
    id integer NOT NULL,
    type "enum_Votes_type",
    scope "enum_Votes_scope" DEFAULT 'regional'::"enum_Votes_scope",
    region "enum_Votes_region" NOT NULL,
    "createdAt" timestamp with time zone NOT NULL,
    "updatedAt" timestamp with time zone NOT NULL,
    "LunchId" integer,
    "UserId" integer,
    "CompetitorId" integer
);

1 个答案:

答案 0 :(得分:0)

您可能需要rank()函数以及某种窗口/分区。看看http://www.postgresql.org/docs/9.4/static/tutorial-window.html

您可以添加

rank() over (order by percent DESC, wins DESC, item.createdAt ASC)

作为查询中的一列,获取您要查找的内容。

您也可以使用Common Table Expressions使查询更容易阅读; http://www.postgresql.org/docs/9.4/static/queries-with.html

例如:

WITH vote_summary AS (
select votes.LunchId, sum((type='up')::int) as wins,
       sum((type='down')::int) as losses
  from votes
 where votes.scope = 'regional'
group by votes.LunchId
)
...

可以为您节省大量的子选择