目标
我有下面的表,
我想选择comment
tbl,
但只返回comment
行检查相关表status
列所有相等的输入参数。
问题
在查询1中,注释掉我突出显示,否则它将返回零行。
要么
查询2获取错误语法
如何解决这个问题?
表
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 = $1
AND u.status = $1
// comment out these for c.endpoint_code 0 (gallery)
AND
CASE WHEN c.endpoint_code = 1
THEN
m.status = $1
END
AND
CASE WHEN c.endpoint_code = 1
THEN
mcbu.status = $1
END
AND
CASE WHEN c.endpoint_code = 1
THEN
mg.status = $1
END
//
// or comment out these for c.endpoint_code 1 (media)
AND
CASE WHEN c.endpoint_code = 0
THEN
g.status = $1
END
AND
CASE WHEN c.endpoint_code = 0
THEN
gcbu.status = $1
END
AND
CASE WHEN c.endpoint_code = 0
THEN
ca.status = $1
END
//
AND c.id = $2
查询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 = $1
AND u.status = $1
CASE WHEN c.endpoint_code = 1
THEN
AND
m.status = $1
AND
mcbu.status = $1
AND
mg.status = $1
END
CASE WHEN c.endpoint_code = 0
THEN
AND
g.status = $1
AND
gcbu.status = $1
AND
ca.status = $1
END
AND c.id = $2
我在javascript中执行此操作从函数中生成查询字符串
输入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 = $1
AND u.status = $1
CASE WHEN c.endpoint_code = 1
THEN
AND
m.status = $1
AND
mcbu.status = $1
AND
mg.status = $1
END
CASE WHEN c.endpoint_code = 0
THEN
AND
g.status = $1
AND
gcbu.status = $1
AND
ca.status = $1
END
`;
}
query += `
AND c.id = $2
`;
在我选择
之后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 = $1
AND u.status = $1
AND
(
(c.endpoint_code = 1
AND m.status = $1
AND mcbu.status = $1
AND mg.status = $1
)
OR
....
json结果因为endpoint_code = 0
所以json键media_gallery
和media
(来自查询部分row_to_json(mg.*) as media_gallery, ...
)值将为null。
或endpoint_code = 1
键gallery
值为空。
如果endpoint_code = 0
然后输出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:
...
答案 0 :(得分:2)
CASE不作为模板工作,而是作为一种功能。更新您的JavaScript,如下所示:
if (inputOption.status != 'undefined') {
query += `
WHERE c.status = $1
AND u.status = $1
AND CASE WHEN c.endpoint_code = 1 -- this will return a boolean
THEN m.status = $1
AND mcbu.status = $1
AND mg.status = $1
END
AND CASE WHEN c.endpoint_code = 0 -- this too
THEN g.status = $1
AND gcbu.status = $1
AND ca.status = $1
END
`;
上述工作,但它不允许PostgreSQL优化查询。如果你使用AND和OR会好得多,正如@jarlh在评论中指出的那样:
if (inputOption.status != 'undefined') {
query += `
WHERE c.status = $1
AND u.status = $1
AND
(
(c.endpoint_code = 1
AND m.status = $1
AND mcbu.status = $1
AND mg.status = $1
)
OR
(c.endpoint_code = 0
AND g.status = $1
AND gcbu.status = $1
AND ca.status = $1)
)
`;
答案 1 :(得分:1)
解决问题的第二部分,您似乎将查询结果检索为单个JSON文档,其中rows
对象是查询返回的实际行数组。如果这是你想要的,那么你可以选择在返回的整行上使用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