sql - 仅连接第二个表中的一行,如果不存在行则返回 null

标签 sql oracle join inner-join

在此查询中,我需要显示左表中的所有记录,并且仅显示右表中结果为最高日期的记录。

当前查询:

SELECT  a.*, c.*
FROM users a 
INNER JOIN payments c
    ON a.id = c.user_ID
INNER JOIN
(
    SELECT user_ID, MAX(date) maxDate
    FROM payments
    GROUP BY user_ID
) b ON c.user_ID = b.user_ID AND
        c.date = b.maxDate
WHERE a.package = 1

这将返回联接有效的所有记录,但我需要显示所有用户,如果他们尚未付款,则付款表中的字段应为空。

我可以使用联合来显示其他行:

SELECT  a.*, c.*
FROM users a 
INNER JOIN payments c
    ON a.id = c.user_ID
INNER JOIN
(
    SELECT user_ID, MAX(date) maxDate
    FROM payments
    GROUP BY user_ID
) b ON c.user_ID = b.user_ID AND
        c.date = b.maxDate
WHERE a.package = 1
union
SELECT  a.*, c.*
FROM users a 
--here I would need to join with payments table to get the columns from the payments table, 
but where the user doesn't have a payment yet
WHERE a.package = 1

使用联合的选项似乎不是一个好的解决方案,但这就是我尝试过的。

最佳答案

因此,换句话说,您需要一个用户列表以及每个用户的最后一次付款。

您可以使用 OUTER APPLY 而不是 INNER JOIN 来获取每个用户的最后一次付款。性能可能会更好,并且对于无需付款的用户,它会按照您想要的方式工作。

SELECT a.*, b.*
FROM   users a
OUTER APPLY ( SELECT * FROM payments c 
              WHERE c.user_id = a.user_id 
              ORDER BY c.date DESC 
              FETCH FIRST ROW ONLY ) b
WHERE a.package = 1;

这是同一概念的通用版本,不需要您的表格(对于其他读者)。它提供数据库用户的列表以及每个用户最近修改的对象。您可以看到它正确包含没有对象的用户。

SELECT a.*, b.*
FROM  all_users a
OUTER APPLY ( SELECT * FROM all_objects b 
              WHERE b.owner = a.username 
              ORDER BY b.last_ddl_time desc 
              FETCH FIRST ROW ONLY ) b

关于sql - 仅连接第二个表中的一行,如果不存在行则返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47230984/

相关文章:

Mysql 列转行(数据透视表)

php - 将全角和半角字符存储在数据库的唯一列中

oracle - 使用 JDBC 连接 Oracle 数据库的 URL 字符串格式

oracle - ORA-12154 : TNS:could not resolve the connect identifier specified (PLSQL Developer)

sql - 使用 N-E-W 表为每一行选择所有外行

c# - 将 SQL NVARCHAR 的值返回到 C# 字符串

mysql - 对 SQL 数据库进行特定更新

mysql - 如何从已创建的表中向 oracle sql Developer 中插入数据

mysql - 来自二度连接的列的总和?

mysql - 在mysql中填充/加入多对多关系表的多个表