if/else 列值,select 不同 table 和列

with if/else column value, select different table and column

objective
我有 table 如下所示, 我要 select comment tbl, 但只有 return comment 行检查相关 table status 列全部等于输入参数。

问题
在查询 1 中,注释掉我突出显示的内容,否则它会起作用 return 零行。 要么 查询 2 得到错误语法

如何解决?

table

comment
id | endpoint_code | endpoint_id | status | create_by_user_id
1  | 1             | 56          | 0      | 1
2  | 0             | 27          | 0      | 1

description:   
endpoint_code  0:gallery tbl 1:media tbl  
use `endpoint_code` value if `0` means `endpoint_id` is point to `gallery` tbl,  
if `1` means point to `media` tbl.


user
id | status 
1  | 0 

gallery
id | status | ...
56 | 0

media
id | status | ...
27 | 0

category_gallery
id | category_id | gallery_id | ...
...

gallery_media
id | gallery_id | media_id | ...
...

查询 1

SELECT c.* ,
  row_to_json(m.*) as media,
  row_to_json(mg.*) as media_gallery,
  row_to_json(g.*) as gallery
  FROM comment c
    LEFT JOIN "user" u ON u.id = c.create_by_user_id

    LEFT JOIN media m ON m.id = c.endpoint_id
      AND c.endpoint_code = 1
    LEFT JOIN "user" mcbu ON mcbu.id = m.create_by_user_id
      AND c.endpoint_code = 1
    LEFT JOIN gallery_media gm ON gm.media_id = c.endpoint_id
      AND c.endpoint_code = 1
    LEFT JOIN gallery mg ON mg.id = gm.gallery_id
      AND c.endpoint_code = 1

    LEFT JOIN gallery g ON g.id = c.endpoint_id
      AND c.endpoint_code = 0
    LEFT JOIN "user" gcbu ON gcbu.id = g.create_by_user_id
      AND c.endpoint_code = 0
    LEFT JOIN category_gallery cg ON cg.gallery_id = g.id
      AND c.endpoint_code = 0
    LEFT JOIN category ca ON ca.id = cg.category_id
      AND c.endpoint_code = 0 

    WHERE c.status =  
      AND u.status =  

      // comment out these for c.endpoint_code 0 (gallery)
      AND 
        CASE WHEN c.endpoint_code = 1
        THEN 
          m.status = 
        END
      AND 
        CASE WHEN c.endpoint_code = 1
        THEN 
          mcbu.status = 
        END
      AND 
        CASE WHEN c.endpoint_code = 1
        THEN 
          mg.status = 
        END
      //


      // or comment out these for c.endpoint_code 1 (media)
      AND 
        CASE WHEN c.endpoint_code = 0
        THEN 
          g.status = 
        END
      AND 
        CASE WHEN c.endpoint_code = 0
        THEN 
          gcbu.status = 
        END
      AND 
        CASE WHEN c.endpoint_code = 0
        THEN 
          ca.status = 
        END
      //

    AND c.id = 

查询 2
错误

SELECT c.* ,
  row_to_json(m.*) as media,
  row_to_json(mg.*) as media_gallery,
  row_to_json(g.*) as gallery
  FROM comment c
    LEFT JOIN "user" u ON u.id = c.create_by_user_id

    LEFT JOIN media m ON m.id = c.endpoint_id
      AND c.endpoint_code = 1
    LEFT JOIN "user" mcbu ON mcbu.id = m.create_by_user_id
      AND c.endpoint_code = 1
    LEFT JOIN gallery_media gm ON gm.media_id = c.endpoint_id
      AND c.endpoint_code = 1
    LEFT JOIN gallery mg ON mg.id = gm.gallery_id
      AND c.endpoint_code = 1

    LEFT JOIN gallery g ON g.id = c.endpoint_id
      AND c.endpoint_code = 0
    LEFT JOIN "user" gcbu ON gcbu.id = g.create_by_user_id
      AND c.endpoint_code = 0
    LEFT JOIN category_gallery cg ON cg.gallery_id = g.id
      AND c.endpoint_code = 0
    LEFT JOIN category ca ON ca.id = cg.category_id
      AND c.endpoint_code = 0 

    WHERE c.status =  
      AND u.status =  

      CASE WHEN c.endpoint_code = 1
      THEN 
        AND 
          m.status = 
        AND 
          mcbu.status = 
        AND 
          mg.status = 
      END


      CASE WHEN c.endpoint_code = 0
      THEN 
        AND 
          g.status = 
        AND 
          gcbu.status = 
        AND 
          ca.status = 
      END

    AND c.id = 

我在 javascript 从函数生成查询字符串
input status params 是如下选项,希望能找到解决上述问题的方法, 最好不要重构代码太多最好

例如查询2

var query = `

SELECT c.* ,
  row_to_json(m.*) as media,
  row_to_json(mg.*) as media_gallery,
  row_to_json(g.*) as gallery
  FROM comment c
    LEFT JOIN "user" u ON u.id = c.create_by_user_id


    LEFT JOIN media m ON m.id = c.endpoint_id
      AND c.endpoint_code = 1
`;

if (inputOption.status != 'undefined') {
query += `
    LEFT JOIN "user" mcbu ON mcbu.id = m.create_by_user_id
      AND c.endpoint_code = 1
    LEFT JOIN gallery_media gm ON gm.media_id = c.endpoint_id
      AND c.endpoint_code = 1
`;
}
query += `
    LEFT JOIN gallery mg ON mg.id = gm.gallery_id
      AND c.endpoint_code = 1
`;

query += `
    LEFT JOIN gallery g ON g.id = c.endpoint_id
      AND c.endpoint_code = 0
`;
if (inputOption.status != 'undefined') {
query += `
    LEFT JOIN "user" gcbu ON gcbu.id = g.create_by_user_id
      AND c.endpoint_code = 0
    LEFT JOIN category_gallery cg ON cg.gallery_id = g.id
      AND c.endpoint_code = 0
    LEFT JOIN category ca ON ca.id = cg.category_id
      AND c.endpoint_code = 0 
`;
}

if (inputOption.status != 'undefined') {
query += `
    WHERE c.status =  
      AND u.status =  

      CASE WHEN c.endpoint_code = 1
      THEN 
        AND 
          m.status = 
        AND 
          mcbu.status = 
        AND 
          mg.status = 
      END


      CASE WHEN c.endpoint_code = 0
      THEN 
        AND 
          g.status = 
        AND 
          gcbu.status = 
        AND 
          ca.status = 
      END
`;
}
query += `
    AND c.id = 
`;

编辑:进一步的问题

我做完后 select

SELECT c.* ,
    row_to_json(mg.*) as media_gallery, 
    row_to_json(m.*) as media,
    row_to_json(g.*) as gallery
  FROM comment c

  LEFT JOIN media m ON m.id = c.endpoint_id

.... other query
  query += `
WHERE c.status =  
  AND u.status =  
  AND
  (
    (c.endpoint_code = 1
     AND m.status = 
     AND mcbu.status = 
     AND mg.status = 
    )
    OR
....

json 结果是因为 endpoint_code = 0 所以在 json 键 media_gallerymedia (从上面的查询部分 row_to_json(mg.*) as media_gallery, ... )值将为空。
endpoint_code = 1gallery 值为空。

How to filter/remove if endpoint_code = 0 then don't output media_gallery media,意思是查询时不做row_to_json(mg.*) as media_gallery, ...?或其他方式?

rows: 
[ { id: 7,
  endpoint_code: 0,
  endpoint_id: 27,
  status: 0,

  media_gallery: null,
  media: null,
  gallery: 
   { id: 27,
     status: 0,
     create_date: 
   ...

尝试获得像

这样的结果
rows: 
[ { id: 7,
  endpoint_code: 0,
  endpoint_id: 27,
  status: 0,

  gallery: 
   { id: 27,
     status: 0,
     create_date: 
   ...

rows: 
[ { id: 7,
  endpoint_code: 1,
  endpoint_id: 27,
  status: 0,

  media_gallery: {
    id: ....
  },
  media: 
   { id: 27,
     status: 0,
     create_date: 
   ...

CASE 不能用作模板,而是用作函数。按如下方式更新您的 javascript:

if (inputOption.status != 'undefined') {
query += `
    WHERE c.status =  
      AND u.status =  

      AND CASE WHEN c.endpoint_code = 1 -- this will return a boolean
      THEN m.status = 
       AND mcbu.status = 
       AND mg.status = 
      END   

      AND CASE WHEN c.endpoint_code = 0 -- this too
      THEN g.status = 
       AND gcbu.status = 
       AND ca.status = 
      END
`;

上面的方法有效,但它不允许 PostgreSQL 优化查询。如果你使用 AND 和 OR 会更好,正如@jarlh 在评论中所说:

if (inputOption.status != 'undefined') {
query += `
    WHERE c.status =  
      AND u.status =  
      AND
      (
        (c.endpoint_code = 1
         AND m.status = 
         AND mcbu.status = 
         AND mg.status = 
        )
        OR
        (c.endpoint_code = 0
         AND g.status = 
         AND gcbu.status = 
         AND ca.status = )
      )
`;

针对问题的第二部分,您似乎将查询结果作为单个 JSON 文档进行检索,其中 rows 对象是返回的实际行的数组通过您的查询。如果这是您想要的,那么您可以 select 在返回的整行上使用 jsonb_strip_nulls() 函数:

SELECT array_to_json(ARRAY(
  SELECT json_strip_nulls(row_to_json(r.*)) AS comment
  FROM (
    SELECT c.* ,
      row_to_json(m.*) as media,
      row_to_json(mg.*) as media_gallery,
      row_to_json(g.*) as gallery
    ...
    ) r
  )) AS rows