SQL 视图,其计数取决于当前用户

问题描述 投票:0回答:1

目标:

  1. 列出所有独特事件
  2. 有一个基于当前用户的名为
    reviewed
    的专用列
  3. 如果当前用户未被邀请,则必须列出事件

可能的情况:

  1. 用户已被邀请
  2. 用户未被邀请

活动由每个“已确认”用户审核(并非所有邀请均已确认) 需“审核”的条件:

  • 存在评论
  • 至少有一个附件链接到此评论

我有4张桌子。

  • 活动
  • 邀请(最多 1 个/用户/活动)
  • 评论(1/邀请)
  • 附件(n/评论)

他们在这里:

CREATE TABLE public.events (
    id bigint NOT NULL,
    name character varying NOT NULL,
    start_at timestamp without time zone NOT NULL,
    end_at timestamp without time zone NOT NULL
);

CREATE TABLE public.invitations (
    id bigint NOT NULL,
    status integer DEFAULT 0 NOT NULL,
    user_id bigint NOT NULL,
    event_id bigint NOT NULL,
);

CREATE TABLE public.reviews (
    id bigint NOT NULL,
    reviewable_id bigint NOT NULL,
    reviewable_type character varying NOT NULL,
    comment text
);

CREATE TABLE public.attachments (
    id bigint NOT NULL,
    attachable_id bigint NOT NULL,
    attachable_type character varying NOT NULL
);

我得到了一个 SQL 视图,但它是错误的,因为

reviewed
与当前用户邀请不匹配(它是随机的,基于邀请创建)。 这是我当前的代码

CREATE OR REPLACE VIEW my_view AS
  SELECT
    ((e.enable_review = true AND r.id IS NOT NULL AND count(a) > 0 ) OR e.enable_review = false)    AS reviewed,
  e.*
  FROM events e
  LEFT JOIN invitations i ON i.event_id = e.id
  LEFT JOIN reviews r ON (r.reviewable_type = 'Invitation' AND r.reviewable_id = i.id)
  LEFT JOIN attachments a ON (a.attachable_type = 'Review' AND a.attachable_id = r.id)
  GROUP BY e.id, r.id;)

我已经阅读了选择每个 GROUP BY 组中的第一行?数十次,但我不确定它是否适合我的情况

在我看来,这个视图是“临时的”,直到我用当前用户邀请来确定结果范围。

我有部分解决方案使用

row_number

CREATE OR REPLACE VIEW my_view AS
  SELECT
    ((e.enable_review = true AND r.id IS NOT NULL AND count(a) > 0 ) OR e.enable_review = false)    AS reviewed,
  e.*,
  row_number() OVER (PARTITION BY i.event_id ORDER BY i.id DESC) AS rn,
  i.id as manual_invitation_id
  FROM events e
  LEFT JOIN invitations i ON i.event_id = e.id
  LEFT JOIN reviews r ON (r.reviewable_type = 'Invitation' AND r.reviewable_id = i.id)
  LEFT JOIN attachments a ON (a.attachable_type = 'Review' AND a.attachable_id = r.id)
  GROUP BY e.id, i.id, r.id;)

然后,当我想要确定当前用户的范围时,我会在

LEFT OUTER JOIN
上使用
manual_invitation_id
,并将其与
WHERE rn=1
组合起来。 但
rn
可以是任何数字,而不仅仅是一个。所以范围不起作用。

我什至不知道是否可以在单个查询中实现。我想避免子查询,因为它是应用程序中最常用的查询之一。此外,它位于 Rails 应用程序内部,因此我不确定是否可以使用 ActiveRecord 轻松处理子查询。

sql ruby-on-rails postgresql sql-view
1个回答
0
投票

要列出所有事件,

EXISTS
子查询可能是最好的。

仍然不清楚当前用户是如何进入这个状态的。这是我的猜测:

SELECT e.enable_review
     , EXISTS (
         SELECT
         FROM   invitations i
         JOIN   reviews     r ON r.reviewable_id = i.id
         JOIN   attachments a ON a.attachable_id = r.id
         WHERE  i.user_id = $current_user_id             -- ???
         AND    i.event_id = e.id
         AND    r.reviewable_type = 'Invitation'
         AND    a.attachable_type = 'Review'
         ) AS reviewed
     , e.*
FROM   events e;
© www.soinside.com 2019 - 2024. All rights reserved.