【问题标题】:Merge IN query in VIEW PostgreSQL在 VIEW PostgreSQL 中合并 IN 查询
【发布时间】:2021-06-02 17:54:49
【问题描述】:

我有两张桌子

  1. 相机
  2. 相机分享

还有一个用户表。

在 Cameras 表中有一个列 owner_id,在 Camera Shares 表中有一个列 user_id

现在还有其他 3 个表格,例如

  1. 档案
  2. 比较
  3. 延时摄影

上面的每个表格都有一个camera_id,通过它连接到相机。

现在我创建了一个视图,它结合了这 3 个表中的所有数据

  1. 档案
  2. 比较
  3. 延时摄影

但是要从该 VIEW 中获取相机列表的数据。这些是我正在做的步骤。

  1. 获取用户提供的 user_id
  2. 查询 owner_id 等于 user_id 的相机表并获取相机 ID。
  3. 查询 user_id 等于 user_id 的相机共享表并获取相机 ID。
  4. 结合第 2 步和第 3 步中的相机 ID。
  5. 针对camera_ids 执行 IN 查询以查看

我的问题:

是否有可能以结合用户数据的方式创建 VIEW。当在 where 子句中传递 user_id 时,它会执行 VIEW 中的第 2、3、4 步。?任何帮助都会很棒。

这是我的观点

  CREATE VIEW archives_view AS
  WITH CORE AS (
    SELECT
      'ARCHIVES' AS TAB_NAME,
      ARC.TITLE,
      ARC.EXID,
      ARC.CREATED_AT,
      ARC.FROM_DATE,
      ARC.TO_DATE,
      NULL AS EMBED_CODE,
      ARC.FILE_NAME,
      ARC.FRAMES,
      ARC.URL,
      ARC.PUBLIC,
      ARC.STATUS,
      ARC.TYPE,
      NULL AS EXTRA,
      ARC.REQUESTED_BY,
      ARC.CAMERA_ID
    FROM
      PUBLIC.ARCHIVES AS ARC
    UNION ALL
    SELECT
      'TIMELAPSES',
      TL.TITLE,
      TL.EXID,
      TL.INSERTED_AT,
      TL.FROM_DATETIME,
      TL.TO_DATETIME,
      NULL AS EMBED_CODE,
      NULL AS FILE_NAME,
      NULL AS FRAMES,
      NULL AS URL,
      NULL AS PUBLIC,
      TL.STATUS,
      NULL AS TYPE,
      TL.EXTRA,
      TL.USER_ID,
      TL.CAMERA_ID
    FROM
      PUBLIC.TIMELAPSES AS TL
    UNION ALL
    SELECT
      'COMPARES',
      COMP.EXID,
      COMP.NAME,
      COMP.INSERTED_AT,
      COMP.BEFORE_DATE,
      COMP.AFTER_DATE,
      COMP.EMBED_CODE,
      NULL AS FILE_NAME,
      NULL AS FRAMES,
      NULL AS URL,
      COMP.PUBLIC,
      COMP.STATUS,
      NULL AS TYPE,
      NULL AS EXTRA,
      COMP.REQUESTED_BY,
      COMP.CAMERA_ID
    FROM
      PUBLIC.COMPARES AS COMP ),
    MORE_INFO AS (
      SELECT
        C.*,
        TRIM(CONCAT(U.FIRSTNAME, ' ', U.LASTNAME)) AS REQUESTER_NAME,
        U.EMAIL AS REQUESTER_EMAIL,
        CAM.EXID AS CAMERA_EXID,
        CAM.NAME,
        CAM.NAME AS CAMERA_NAME,
        CAM.TIMEZONE AS CAMERA_TIMEZONE,
        U.ID AS USER_ID
      FROM
        CORE C
      JOIN USERS U ON
        C.REQUESTED_BY = U.ID
      JOIN CAMERAS CAM ON
        C.CAMERA_ID = CAM.ID )
      SELECT
        *
      FROM
        MORE_INFO
      order by CREATED_AT DESC;

如果您想使用数据库和数据,则可以使用 DDL here

【问题讨论】:

标签: sql postgresql


【解决方案1】:

返回表格而不是视图的函数

CREATE FUNCTION archives_view(int) RETURNS TABLE(
  tab_name text,
  title    text,
  exid     text,
  created_at timestamptz,
  from_date  timestamptz,
  to_date    timestamptz,
  embed_code text,
  file_name  text,
  frames     int,
  url        text,
  public boolean,
  status int,
  type   text,
  extra  json,
  requested_by int,
  camera_id int,
  requester_name text,
  requester_email text, 
  camera_exid text, 
  name text,    
  camera_name text,
  camera_timezone text,
  user_id int
)
AS
$$ 
  WITH CORE AS (
    SELECT
      'ARCHIVES' AS TAB_NAME,
      ARC.TITLE,
      ARC.EXID,
      ARC.CREATED_AT,
      ARC.FROM_DATE,
      ARC.TO_DATE,
      NULL AS EMBED_CODE,
      ARC.FILE_NAME,
      ARC.FRAMES,
      ARC.URL,
      ARC.PUBLIC,
      ARC.STATUS,
      ARC.TYPE,
      NULL AS EXTRA,
      ARC.REQUESTED_BY,
      ARC.CAMERA_ID
    FROM
      PUBLIC.ARCHIVES AS ARC
    UNION ALL
    SELECT
      'TIMELAPSES',
      TL.TITLE,
      TL.EXID,
      TL.INSERTED_AT,
      TL.FROM_DATETIME,
      TL.TO_DATETIME,
      NULL AS EMBED_CODE,
      NULL AS FILE_NAME,
      NULL AS FRAMES,
      NULL AS URL,
      NULL AS PUBLIC,
      TL.STATUS,
      NULL AS TYPE,
      TL.EXTRA,
      TL.USER_ID,
      TL.CAMERA_ID
    FROM
      PUBLIC.TIMELAPSES AS TL
    UNION ALL
    SELECT
      'COMPARES',
      COMP.EXID,
      COMP.NAME,
      COMP.INSERTED_AT,
      COMP.BEFORE_DATE,
      COMP.AFTER_DATE,
      COMP.EMBED_CODE,
      NULL AS FILE_NAME,
      NULL AS FRAMES,
      NULL AS URL,
      COMP.PUBLIC,
      COMP.STATUS,
      NULL AS TYPE,
      NULL AS EXTRA,
      COMP.REQUESTED_BY,
      COMP.CAMERA_ID
    FROM
      PUBLIC.COMPARES AS COMP ),
    MORE_INFO AS (
      SELECT
        C.*,
        TRIM(CONCAT(U.FIRSTNAME, ' ', U.LASTNAME)) AS REQUESTER_NAME,
        U.EMAIL AS REQUESTER_EMAIL,
        CAM.EXID AS CAMERA_EXID,
        CAM.NAME,
        CAM.NAME AS CAMERA_NAME,
        CAM.TIMEZONE AS CAMERA_TIMEZONE,
        U.ID AS USER_ID
      FROM
        CORE C
      JOIN USERS U ON
        C.REQUESTED_BY = U.ID AND U.ID = $1
      JOIN CAMERAS CAM ON
        C.CAMERA_ID = CAM.ID )
      SELECT
        *
      FROM
        MORE_INFO
$$
    LANGUAGE SQL;

使用,选择userId=1的数据

select * 
from archives_view(1)
order by CREATED_AT DESC;

db<>fiddle

【讨论】:

  • 问题是:我不想要requested_at 应该等于user_id 的所有数据。但requested_id 可以不同。 user_id的作用只是获取camera_ids
  • 在上面的例子中甚至没有使用camera_shares表,我想你误解了这个问题?
  • @JunaidFarooq,很可能。您可以通过将..= $1 谓词放在真正需要的位置来轻松调整代码。
  • 但是第2步和第3步和第4步的主要问题是什么?这将如何解决?
  • 期望的输出是什么?编辑您的问题以在您的小提琴中显示输入数据。
猜你喜欢
  • 2015-09-04
  • 2013-03-28
  • 2016-10-30
  • 2015-03-23
  • 1970-01-01
  • 2012-01-17
  • 2019-06-22
  • 1970-01-01
相关资源
最近更新 更多