计算在select语句中匹配的项目

时间:2013-08-30 15:01:06

标签: sql select count large-data

我们有一个针对一些相当大的表执行的存储过程,并且在连接到更大的表时,它还保持与相应的batch_id匹配的记录数。我想弄清楚的是,我可以用计数或其他方法来改进这个吗?试图摆脱嵌套的SELECT COUNT(*)语句。 CCTransactions表是140万行,BatchItems是660万行。

SELECT  a.ItemAuthID, a.FeeAuthID, a.Batch_ID, a.ItemAuthCode, 
        a.FeeAuthCode, b.Amount, b.Fee, 
  (SELECT COUNT(*) FROM BatchItems WHERE Batch_ID = a.Batch_ID) AS BatchCount,
  ItemBillDate, FeeBillDate, b.AccountNumber, 
  b.Itemcode, ItemAuthToken, FeeAuthToken,
  cc.ItemMerchant, cc.FeeMerchant
  FROM CCTransactions a WITH(NOLOCK)
        INNER JOIN BatchItems b WITH(NOLOCK)
              ON a.Batch_ID = b.Batch_ID
        INNER JOIN CCConfig cc WITH(NOLOCK)
              ON a.ClientCode = cc.ClientCode
  WHERE ((ItemAuthCode > '' AND ItemBillDate IS NULL)
              OR (FeeAuthCode > '' AND FeeBillDate IS NULL))
              AND TransactionDate BETWEEN DATEADD(d,-7,GETDATE()) 
              AND convert(char(20),getdate(),101)  + ' ' +   @Cutoff
  ORDER BY TransactionDate

1 个答案:

答案 0 :(得分:0)

当您的DBMS支持WIndowed Aggregate Functions时,您可以将其重写为

COUNT(*) OVER (PARTITION BY Batch_ID)

当然这只返回SELECT返回的每个Batch_ID的行数。如果内部联接导致行数减少,则不是正确的数字。

然后将标量子查询重写为连接可能更有效(取决于您的DBMS):

SELECT  a.ItemAuthID, a.FeeAuthID, a.Batch_ID, a.ItemAuthCode, 
        a.FeeAuthCode, b.Amount, b.Fee, 
  dt.BatchCount,
  ItemBillDate, FeeBillDate, b.AccountNumber, 
  b.Itemcode, ItemAuthToken, FeeAuthToken,
  cc.ItemMerchant, cc.FeeMerchant
  FROM CCTransactions a WITH(NOLOCK)
        INNER JOIN BatchItems b WITH(NOLOCK)
              ON a.Batch_ID = b.Batch_ID
        INNER JOIN CCConfig cc WITH(NOLOCK)
              ON a.ClientCode = cc.ClientCode
        INNER JOIN
          ( 
            SELECT BatchCount, COUNT(*) AS BatchCount
            FROM BatchItems 
            GROUP BY Batch_ID
          ) AS dt ON a.Batch_ID = dt.Batch_ID
  WHERE ((ItemAuthCode > '' AND ItemBillDate IS NULL)
              OR (FeeAuthCode > '' AND FeeBillDate IS NULL))
              AND TransactionDate BETWEEN DATEADD(d,-7,GETDATE()) 
              AND convert(CHAR(20),getdate(),101)  + ' ' +   @Cutoff
  ORDER BY TransactionDate