我正在try 使用以下查询列出在过go 30天内没有购买的所有客户:

SELECT c.*
FROM customers c
WHERE NOT EXISTS (
    SELECT 1
    FROM purchases p 
    WHERE c.customer_id = p.customer_id 
      AND p.PURCHASE_DATE >= TRUNC(SYSTIMESTAMP) - NUMTODSINTERVAL (30, 'DAY')
      AND p.PURCHASE_DATE < TRUNC(SYSTIMESTAMP));

这将产生以下输出:

CUSTOMER_ID FIRST_NAME LAST_NAME
1 Faith Mazzarone
2 Lisa Saladino

此查询似乎正在运行.

但我也希望显示最后的"purchase_date"值以及客户信息,或者如果客户从未购买过产品,则显示NULL.我似乎想不出该怎么做.

有没有人能帮帮我?

以下是重现我的环境的DDL:

ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'DD-MON-YYYY  HH24:MI:SS.FF';

ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-YYYY HH24:MI:SS';

CREATE TABLE customers 
(CUSTOMER_ID, FIRST_NAME, LAST_NAME) AS
SELECT 1, 'Faith', 'Mazzarone' FROM DUAL UNION ALL
SELECT 2, 'Lisa', 'Saladino' FROM DUAL UNION ALL
SELECT 3, 'Jerry', 'Torchiano' FROM DUAL;

CREATE TABLE items 
(PRODUCT_ID, PRODUCT_NAME, PRICE) AS
SELECT 100, 'Black Shoes', 79.99 FROM DUAL UNION ALL
SELECT 101, 'Brown Pants', 111.99 FROM DUAL UNION ALL
SELECT 102, 'White Shirt', 10.99 FROM DUAL;

CREATE TABLE purchases
(CUSTOMER_ID, PRODUCT_ID, QUANTITY, PURCHASE_DATE) AS
SELECT 1, 101, 3, TIMESTAMP'2022-10-11 09:54:48' FROM DUAL UNION ALL
SELECT 1, 100, 1, TIMESTAMP '2022-10-12 19:04:18' FROM DUAL UNION ALL
SELECT 2, 101,1, TIMESTAMP '2022-10-11 09:54:48' FROM DUAL UNION ALL
SELECT 2, 101, 3, TIMESTAMP '2022-10-17 19:34:58' FROM DUAL UNION ALL
SELECT 3, 101,1, TIMESTAMP '2022-12-11 09:54:48' FROM DUAL UNION ALL
SELECT 3, 102,1, TIMESTAMP '2022-12-17 19:04:18' FROM DUAL UNION ALL
SELECT 3, 102, 4,TIMESTAMP '2022-12-12 21:44:35' + NUMTODSINTERVAL ( LEVEL * 2, 'DAY') FROM    dual
CONNECT BY  LEVEL <= 5;

推荐答案

通过使用Max()函数获取每个客户的最新购买日期,然后将该信息与Customers表连接起来,您可以显示最后一次购买日期以及客户信息.

SELECT c.*, p.last_purchase
FROM customers c
LEFT JOIN (SELECT customer_id, MAX(purchase_date) as last_purchase
           FROM purchases
           GROUP BY customer_id) p
ON c.customer_id = p.customer_id
WHERE NOT EXISTS (SELECT 1
                  FROM purchases p 
                  WHERE c.customer_id  = p.customer_id AND                                              
                  p.PURCHASE_DATE >= TRUNC(SYSTIMESTAMP) - NUMTODSINTERVAL (30, 'DAY') AND
                  p.PURCHASE_DATE < TRUNC(SYSTIMESTAMP)  
                 );

Sql相关问答推荐

如何在联接条件不匹配时按日期获取上一条记录

在请求结束之前,PostgreSQL不会考虑使用中的删除

LEFT JOIN不显示计数0我期望的方式

在SQL中使用类别值将行转置为列

Access VBA SQL命令INSERT FOR MULTIME VALUE

使用列表作为参数进行 Select ,如果为空,则在PostgreSQL中不使用参数进行 Select

从包含PostgreSQL中的JSON值的列中提取列表或目录

Oracle分层查询-两条路径在末尾合并为一条

每小时 Select 1行

更改重复值的情况

当我返回 sql 列时,有没有办法只反转数字? ( hebrew )

列(值不为空)到其他有序列

如何从三个连接表中获取数据,并始终显示第一个表中的数据,以及第三个表中的空值或现有记录?

更新之前如何获得价值

带聚合函数的 percentile_cont

连续期间的缺口

如何通过存储过程将 root 的下一个子 node 作为父 node ?

SQL 计数和过滤查询优化

在 PostgreSQL 中,如何将数组中的每个元素用作另一个表中的键?

SQL:有没有办法根据另一列的数据细节过滤和形成另一列?