如何更有效地编写此查询?

时间:2015-04-10 04:18:36

标签: sql sql-server

此查询在循环中工作,因此其性能太慢。 FUID由while循环提供。

SELECT (SELECT TOP 1 AmountPaid 
        from [xyz].[dbo].AmountReceived 
          WHERE C.IID = [xyz].[dbo].AmountReceived.IID 
        order by ReceivingDate asc)
FROM [xyz].[dbo].Customer C
  Where C.BuisnessDate >= DATEADD(m,DATEDIFF(m,0,'2015-03-31'),0) 
  AND C.BuisnessDate <= DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,'2015-03-31')+1,0)) AND C.FUID=16 
  AND DATEDIFF(M,C.RiskDate,'2015-03-31') <=3

Customer表包含以下相关列:

 +------------+----+----------+----------+
 |   IID  | FUID |BusinessDate|RiskDate  |
 +--------+------+------------+----------+
 | 22433  | 13   |2013-05-02  |2007-05-23|
 | 22443  | 26   |2014-02-18  |2011-09-07|
 | 22906  | 32   |2014-12-22  |2015-01-12|

AmountReceived表:

 +--------+---------------+-------------+
 |   IID  |AmountPaid     |ReceivingDate|
 +--------+---------------+-------------+
 | 22433  | 13800         |2015-02-02   |
 | 22443  | 1290          |2014-12-18   |
 | 22906  | 408           |2014-10-22   |

1 个答案:

答案 0 :(得分:1)

如果我理解了您的问题而您只在FUID中获得了WHILE,那么您需要这样的内容

;WITH CTE AS 
(
SELECT  C.FUID,AR.AmountPaid,
ROW_NUMBER()OVER(PARTITION BY C.FUID ORDER BY AR.ReceivingDate ASC) rn
FROM [xyz].[dbo].Customer C
    INNER JOIN [xyz].[dbo].AmountReceived AR
        ON C.IID = AR.IID 
WHERE C.BuisnessDate >= DATEADD(m,DATEDIFF(m,0,'2015-03-31'),0) 
    AND C.BuisnessDate <= DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,'2015-03-31')+1,0))
    AND C.FUID BETWEEN 1 AND 47 
    AND C.RiskDate >= '2014-12-01'
)
SELECT C.FUID,AR.AmountPaid
FROM CTE 
WHERE rn = 1

还在上面的评论中添加了thepirat000的建议,将DATEDIFF(M,C.RiskDate,'2015-03-31') <=3更改为C.RiskDate >= '2014-12-01'