在条件为null的情况下连接表

时间:2012-11-09 03:08:12

标签: sql sql-server tsql sql-server-2005

我有表MemberTransaction。表格Member有两列MemberIDMemberName。表格Transaction有3列,MemberIDTransactionDateMemberBalance

表格中的行如下所示:

Member

MemberID           MemberName
=============================
1                  John
2                  Betty
3                  Lisa

Transaction

MemberID        TransactionDate         MemberBalance
=====================================================
1               13-12-2012              200
2               12-12-2012              90
1               10-09-2012              300

我想查询MemberID, MemberNameMemberBalance,其中TransactionDate是每个MemberID的最新(最大)。

我的查询是这样的:

SELECT 
    t.MemberID, m.MemberName , t.MemberBalance
FROM 
    Member AS m 
INNER JOIN 
    Transaction AS t ON m.MemberID = t.MemberID 
WHERE 
    t.TransactionDate IN (SELECT MAX(TransactionDate)
                          FROM Transaction 
                          GROUP BY MemberID)

此查询返回:

MemberID           MemberName         MemberBalance
===================================================
1                  John               200
2                  Betty              90

我的问题是,我希望查询返回:

MemberID           MemberName         MemberBalance
===================================================
1                  John               200
2                  Betty              90
3                  Lisa               NULL

即使MemberID表中不存在Transaction,我也希望显示该成员。

我该怎么做?

谢谢。

5 个答案:

答案 0 :(得分:5)

您也可以使用以下内容:

SELECT m.MemberID, m.MemberName, t1.MemberBalance
FROM Member AS m 
LEFT JOIN
(
  select max(transactionDate) transactionDate, 
    MemberID
  from Transactions
  group by MemberID
) AS t 
  ON m.MemberID = t.MemberID 
left join transactions t1
  on t.transactionDate = t1.transactionDate
  and t.memberid = t1.memberid

请参阅SQL Fiddle with Demo

答案 1 :(得分:2)

  即使其TransactionID在Transaction表中不存在

,也要显示

成员

您可以使用Member表上的LEFT JOIN将行保留到Transaction表。

  

其中TransactionDate是每个MemberID的最新(最大)。

从SQL Server 2005开始,首选且性能更佳的方法是使用ROW_NUMBER()

   SELECT MemberID, MemberName, MemberBalance
     FROM (
   SELECT m.MemberID, m.MemberName , t.MemberBalance,
          row_number() over (partition by m.MemberID order by t.TransactionDate desc) rn
     FROM Member AS m 
LEFT JOIN [Transaction] AS t ON m.MemberID = t.MemberID 
        ) X
    WHERE rn=1;

答案 2 :(得分:2)

要将成员保留在结果集中,您需要外部联接。

此外,请不要忘记在内部选择查询的memberid上添加条件,因为当一个用户的最大日期与另一个用户的非最大日期匹配时,您可能会遇到问题(您的where条件将通过两次第二个用户作为他的交易日期将在选择的结果上出现两次,一个是他的实际最大日期,另一个是 - 某个用户匹配非最大日期的最大日期)

答案 3 :(得分:1)

您需要使用LEFT JOIN。您的查询中也有错误,因为如果两个成员同时拥有事务,则可以为这两个用户获取两行。

试试这个

SELECT t.MemberID, m.MemberName , t.MemberBalance
FROM Member AS m 
    LEFT JOIN Transaction AS t ON m.MemberID = t.MemberID AND t.TransactionDate=
    ( 
        SELECT MAX(TransactionDate)
        FROM Transaction T2
        WHERE T2.MemberID=t.MemberID
    )

答案 4 :(得分:0)

SELECT a.MemberId,a.MemberName,a.MemberBalance
FROM
(
SELECT m.MemberId,m.MemberName,t1.MemberBalance
      ,ROW_NUMBER() OVER(PARTITION BY m.MemberId ORDER BY t1.TransactionDate DESC) AS RN
FROM
@Member m OUTER APPLY (SELECT t.MemberId,t.MemberBalance,t.TransactionDate
                       FROM @Transaction t WHERE m.MemberId=t.MemberId) t1
)a
WHERE a.RN=1