postgresql-检查使用case和exists的表之间是否存在关系
这是我的打包桌 它通过object_tags表连接到tags表,object_id是package.id 如果包装上有特殊标签,或者从今天起购买日期超过3天或更长时间,则包装可被视为特殊包装。这就是输出应该是什么:postgresql-检查使用case和exists的表之间是否存在关系,sql,postgresql,Sql,Postgresql,这是我的打包桌 它通过object_tags表连接到tags表,object_id是package.id 如果包装上有特殊标签,或者从今天起购买日期超过3天或更长时间,则包装可被视为特殊包装。这就是输出应该是什么: +------------+--------------+--------+ | package_id | order_number | is_vip | +------------+--------------+--------+ | 1 | P1
+------------+--------------+--------+
| package_id | order_number | is_vip |
+------------+--------------+--------+
| 1 | P1 | 0 |
| 2 | P2 | -1 |
| 3 | P3 | -1 |
| 4 | P4 | -1 |
| 5 | P5 | 0 |
+------------+--------------+--------+
这就是我尝试过的:
SELECT packages.id as package_id,
packages.order_number as order_number,
(CASE
WHEN EXISTS(SELECT p.id as id
FROM packages p
INNER JOIN object_tags ot on ot.object_id = p.id
INNER JOIN tags t on t.id = ot.tag_id
WHERE tag.name = 'special'
)vip on packages.id = vip.id THEN -1 /*(PG::SyntaxError: ERROR: syntax error at or near "vip"*/
WHEN p.purchased_at NOT BETWEEN NOW() AND NOW() - interval '3 days' then -1
ELSE 0 END) as is_vip
FROM packages p
我不太确定这件事——这是其中的一部分。任何帮助都将不胜感激 在修复了一些语法错误后,这种方法会起作用,但我认为exists子句不是实现这一点的最干净的方法。像这样的怎么样
select P.id package_id
, P.order_number
, (P.purchase_date < (now() - interval '3 days') or T.name = 'special') is_vip
from packages P
left join object_tags OT
on P.id = OT.object_id
left join tags T
on OT.tag_id = T.id
and T.name = 'special'
如果需要将true映射为0,可以将其包装在子查询中。使用特殊的\u包
像
选择package.id
从包、对象、标签、标签
其中package.id=object\u tags.object\u id
AND tags.id=object\u tags.tag\u id
AND tags.name='special'
选择package.id作为package\u id,
包装订单号,
案例
当package.purchase\u日期<现在-间隔“3天”然后-1
当special_packages.id不为空时,则为-1
其他0
一如继往
从包装
使用id左键连接特殊_包
这是一个例子。如果您的数据库不支持CTE,则可以将特殊_包移动到子查询中:
选择
从包装
左连接。。。作为使用id的特殊_包
在p.id的末尾有一个逗号作为id,它不应该在那里……使用0和-1作为Is_vip列的值有什么特殊原因吗?如果不是,布尔值更有意义。@Nick yep。将更新问题。thanks@SimonLepkin是的,稍后我会处理它们。packages.id=vip.id在查询中没有位置。不知道你想用它实现什么?谢谢!我没想过要加入左撇子!:
SELECT packages.id as package_id,
packages.order_number as order_number,
(CASE
WHEN EXISTS(SELECT p.id as id
FROM packages p
INNER JOIN object_tags ot on ot.object_id = p.id
INNER JOIN tags t on t.id = ot.tag_id
WHERE tag.name = 'special'
)vip on packages.id = vip.id THEN -1 /*(PG::SyntaxError: ERROR: syntax error at or near "vip"*/
WHEN p.purchased_at NOT BETWEEN NOW() AND NOW() - interval '3 days' then -1
ELSE 0 END) as is_vip
FROM packages p
select P.id package_id
, P.order_number
, (P.purchase_date < (now() - interval '3 days') or T.name = 'special') is_vip
from packages P
left join object_tags OT
on P.id = OT.object_id
left join tags T
on OT.tag_id = T.id
and T.name = 'special'
SELECT package.id AS package_id, package.order_number AS order_number,
CASE
WHEN 'special' = (SELECT tags.name FROM tags WHERE tags.id = object_tags.tag_id)
THEN -1
WHEN package.purchase_date < NOW() - interval '3 days'
THEN -1
ELSE 0
END AS is_vip
FROM package
LEFT JOIN object_tags ON package.id = object_tags.object_id
ORDER BY packages.id