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_gallery
和 media
(从上面的查询部分 row_to_json(mg.*) as media_gallery, ...
)值将为空。
或 endpoint_code = 1
键 gallery
值为空。
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
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_gallery
和 media
(从上面的查询部分 row_to_json(mg.*) as media_gallery, ...
)值将为空。
或 endpoint_code = 1
键 gallery
值为空。
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