sql - postgresql - 使用大小写检查表之间是否存在关系并存在

标签 sql postgresql

这是我的

+----+--------------+---------------+
| id | order_number | purchase_date |
+----+--------------+---------------+
|  1 | P1           | 11-22-2019    |
|  2 | P2           | 11-21-2019    |
|  3 | P3           | 11-20-2019    |
|  4 | P4           | 11-17-2019    |
|  5 | P5           | 11-21-2019    |
+----+--------------+---------------+

它通过 object_tags 表连接到 tags 表,其中 object_idpackage.id

        object_tags                 tags

+----+-----------+--------+    +----+---------+
| id | object_id | tag_id |    | id |  name   |
+----+-----------+--------+    +----+---------+
|  1 |         2 |      1 |    |  1 | special |
|  2 |         3 |      1 |    |  2 | normal  |
+----+-----------+--------+    +----+---------+

如果包裹有标签 special 或者 purchase_date 超过 3 天或更长时间,则包裹可以被视为 special 包裹今天。输出应该是这样的:

+------------+--------------+--------+
| 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

我不太确定其中的 CASE - EXISTS 部分。任何帮助,将不胜感激。

最佳答案

  WITH special_packages
    AS (
         SELECT package.id
           FROM package, object_tags, tags
          WHERE package.id = object_tags.object_id
            AND tags.id = object_tags.tag_id
            AND tags.name = 'special'
       )
SELECT package.id AS package_id,
       package.order_number,
       CASE
         WHEN package.purchase_date < NOW() - interval '3 days' THEN -1
         WHEN special_packages.id IS NOT NULL THEN -1
         ELSE 0
       END AS is_vip
  FROM package
  LEFT JOIN special_packages USING (id)

这是一个 SQL Fiddle .如果您的数据库不支持 CTE,那么您可以将 special_packages 移动到子查询中:

SELECT ...
  FROM package
  LEFT JOIN ( ... ) AS special_packages USING (id)

关于sql - postgresql - 使用大小写检查表之间是否存在关系并存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58987533/

相关文章:

mysql - 在 Select 中使用的 CASE 中将字段与纯文本连接起来?

python - 无法比较 Postgresql sqlalchemy.exc.ProgrammingError ProgrammingError : (ProgrammingError) can't adapt type 'time.struct_time' 中的日期时间

sql - 将多个 upsert 语句的结果捕获到 Postgresql 的一个输出中

PostgreSQL 将不同的属性连接在一起以返回单个值

java - 如何使用 JDBC 取消 PostgreSQL 中长时间运行的查询?

sql - 如果不是今天的日期,则条件查询返回时间戳,否则返回时间

mysql - 具有某些条件的 SQL 查询运行缓慢 - MySQL

c# - 将显示的查询/子查询转换为分组依据?

sql - 如何对 Apache Hive SQL 代码执行 SonarQube 分析?

MySQL左连接优化