【问题标题】:Problem joining tables in SQL在 SQL 中连接表的问题
【发布时间】:2011-10-25 06:41:30
【问题描述】:
SELECT MID, FAD.FirstOpenedDate ,LCD.LastCloseDate
FROM mwMaster.dbo.Merchant M
JOIN        (
            SELECT MerchID, MIN(moddate) AS FirstOpenedDate
            FROM mwMaster.dbo.MerchantStatusHistory
            GROUP BY MerchID
            )   FAD ON FAD.MerchID = M.MerchID 
LEFT JOIN   (
            SELECT MerchID, MAX(moddate) AS LastCloseDate
            FROM mwMaster.dbo.MerchantStatusHistory
            GROUP BY MerchID
            )   LCD ON LCD.MerchID = M.MerchID
JOIN        (
            SELECT merchid ,avg(Transactions) ,avg(Profit) 
            FROM mwMaster.dbo.ResidualSummary RS
            WHERE RS.Date_Processed < LCD.LastCloseDate
            GROUP BY Merchid    
            )   R ON R.MerchID = M.MerchID 

我在执行以下联接时遇到问题。我之前遇到过这个问题并使用过临时表,但想找出我做错了什么。基本上不工作的线是倒数第三条。 “

有什么想法吗?

在旁注中,我还看到人们使用 CROSS 和 OVER。不熟悉它的工作原理,但可能适用于这里?

【问题讨论】:

  • 你能用简单的英语解释一下你想在这里实现什么吗?
  • 使用嵌套查询加入表,并在 select 语句的 where 子句中使用上面创建的表中的列之一
  • @marc - 看起来问题是他想在另一个子查询中使用对子查询的引用,基本上。
  • 是否需要最后一个连接?我没有看到您引用了 R 子查询中的任何列。
  • @Conrad Frix:是的,但是如果不需要列,我们可以消除计算聚合的开销,并可能使用WHERE EXISTS... 而不是JOIN 来改进。跨度>

标签: sql tsql join nested-sets


【解决方案1】:

我认为虽然没有测试,但您可以在 SQL 2005+ 中将您的 JOIN 更改为 CROSS APPLY

SELECT MID, FAD.FirstOpenedDate ,LCD.LastCloseDate
FROM mwMaster.dbo.Merchant M
JOIN        (
            SELECT MerchID, MIN(moddate) AS FirstOpenedDate
            FROM mwMaster.dbo.MerchantStatusHistory
            GROUP BY MerchID
            )   FAD ON FAD.MerchID = M.MerchID 
LEFT JOIN   (
            SELECT MerchID, MAX(moddate) AS LastCloseDate
            FROM mwMaster.dbo.MerchantStatusHistory
            GROUP BY MerchID
            )   LCD ON LCD.MerchID = M.MerchID
CROSS APPLY(
        SELECT merchid ,avg(Transactions) ,avg(Profit) 
        FROM mwMaster.dbo.ResidualSummary RS
        WHERE RS.Date_Processed < LCD.LastCloseDate
        GROUP BY Merchid    
        )   R ON R.MerchID = M.MerchID 

但使用 CTE 可能更容易

 WITH LCD AS (SELECT MerchID, MAX(moddate) AS LastCloseDate
        FROM mwMaster.dbo.MerchantStatusHistory
        GROUP BY MerchID),
  R AS (
              SELECT merchid ,avg(Transactions) ,avg(Profit) 
              FROM mwMaster.dbo.ResidualSummary RS
                   INNER JOIN LCD on 
                   LCD.MERCHID = RS.MERCHID
              WHERE RS.Date_Processed < LCD.LastCloseDate
              GROUP BY Merchid    
            )

SELECT MID, FAD.FirstOpenedDate ,LCD.LastCloseDate
FROM mwMaster.dbo.Merchant M
JOIN        (
            SELECT MerchID, MIN(moddate) AS FirstOpenedDate
            FROM mwMaster.dbo.MerchantStatusHistory
            GROUP BY MerchID
            )   FAD ON FAD.MerchID = M.MerchID 
LEFT JOIN LCD ON LCD.MerchID = M.MerchID
LEFT JOIN R ON R.MerchID = M.MerchID 

【讨论】:

  • 同意,我通常认为 CTE 是最简单/最简单的方法。虽然,为什么不在LCD CTE 中包含剩余的子选择 (MIN(moddate))?连接条件相同(相同的表和列,LEFT JOIN LCD 没有意义,因为以前需要 JOIN),可以是相同表/索引查找的一部分。
【解决方案2】:

如果没有您的数据,我无法真正对此进行测试,但您可以通过以下方式进行测试:

SELECT MID,
       MIN(moddate) OVER (PARTITION BY MerchID) as FirstOpenedDate,
       MAX(moddate) OVER (PARTITION BY MerchID) as LastCloseDate
FROM mwMaster.dbo.Merchant
HAVING DateProcessed < LastCloseDate

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多