【问题标题】:SQL Query too slowSQL 查询太慢
【发布时间】:2012-12-18 06:14:27
【问题描述】:

我的要求是只选择没有交易的客户,否则他们的最后一笔交易是在某个日期之后。

目前,我的查询耗时过长。

有没有更有效的方法来做到这一点?

SELECT *, 
   (SELECT MAX(AC_CLOSEDDAT) FROM 
    Accs WHERE accs.AC_CLIENTCODE = c.CL_CLIENTCODE) AS LastTrans 
FROM Clients c 
WHERE CL_STATUS <> 'R' 
AND STORE_CODE = '69JX

我希望我可以使用 JOIN,但不确定....我需要没有交易的客户,以及过去 2 年内有交易的客户。

使用 SQL Server 2008。

【问题讨论】:

    标签: sql sql-server-2008 query-optimization


    【解决方案1】:

    您可以使用 NOT EXISTS 子句,它将在给定日期之后为您提供空交易或无交易的结果,而无需任何最大值。

    SELECT * FROM Clients c
    WHERE CL_STATUS <> 'R'
    AND STORE_CODE = '69JX'
    AND NOT EXISTS 
        (SELECT NULL FROM Accs a
        WHERE a.AC_CLIENTCODE = c.CL_CLIENTCODE
        AND a.AC_CLOSEDDAT > theDateToCompare)
    

    【讨论】:

    • 这可能有效 - 但我不确定两件事:1. 为什么选择 'SELECT NULL',而不是 'SELECT *'?以及 2. 这是否包括在 Accs 中有 0 行的客户?
    • @Craig 1. 因为它只是对“存在”的检查,所以您不想从检查中检索任何行。 2. 是的。
    【解决方案2】:

    嗯,你可以使用JOIN,只是它需要是LEFT JOIN:

    SELECT c.*, MAX(AC_CLOSEDDAT) AS LastTrans
        FROM Clients c 
        LEFT JOIN Accs ON accs.AC_CLIENTCODE = c.CL_CLIENTCODE 
    WHERE CL_STATUS <> 'R' 
        AND STORE_CODE = '69JX
    

    使用 LEFT JOIN 将返回所有来自 Clients 的记录,无论 Accs 表中是否存在对应关系。

    【讨论】:

      【解决方案3】:

      通过加入,您可以:

      SELECT c.client_id
      FROM Clients c 
      LEFT JOIN  Accs a
        on (a.AC_CLIENTCODE = c.CL_CLIENTCODE AND 
            a.AC_CLOSEDDAT >= DATEADD(year,-2,GETDATE())
      WHERE CL_STATUS <> 'R'
      AND STORE_CODE = '69JX'
      group by c.client_id;
      

      但 Raphaël Althaus 的答案是最好的 SQL,并且引擎知道使用哈希联接(最终)执行它。

      【讨论】:

      • 这看起来也不错 - 但它是否也包括没有 Accs 行的客户端?
      • 是的,您将获得所有客户端,因为它是 left join,但如果您在 select 子句中添加列,您还需要在 group by 子句中添加它们
      猜你喜欢
      • 1970-01-01
      • 2021-12-31
      • 2022-01-27
      • 2013-07-10
      • 2017-03-24
      • 1970-01-01
      • 1970-01-01
      • 2021-06-23
      • 2021-06-19
      相关资源
      最近更新 更多