简体   繁体   中英

Merge IN query in VIEW PostgreSQL

I have 2 tables

  1. Cameras
  2. Camera Shares

and a User table.

in the Cameras table, there is a column owner_id and in the Camera Shares table there is a column user_id .

Now there are other 3 tables such as

  1. Archives
  2. Compares
  3. Timelapses

each above tables have a camera_id through which they are connected to the camera.

Now I have created a view, which combines all the data from these 3 tables

  1. Archives
  2. Compares
  3. Timelapses

But to get data from that VIEW for a list of cameras. these are the steps I am doing.

  1. get a user_id provided by a user
  2. Query cameras table where the owner_id is equal to user_id and get camera ids.
  3. Query camera shares table where user_id is equal to user_id and get camera ids.
  4. Combine the camera ids from Step 2 and Step 3.
  5. Perform an IN query to VIEW against the camera_ids

My question:

Is it possible to create the VIEW in such a way that it combines data for a user. when a user_id is passed in where clause, It does the Step 2, 3, 4 in VIEW.? any help would be great.

This is my VIEW

  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;

If you want to play with Database and data then DDL is available here .

A function returning a table instead of a view

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;

Usage, select data for userId=1

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

db<>fiddle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM