添加计数到查询而不复制原始选择查询

时间:2014-08-06 02:27:36

标签: sql sql-server count

我有以下代码。

SELECT
   _bvSerialMasterFull.SerialNumber,    _bvSerialMasterFull.SNStockLink,
   _bvSerialMasterFull.SNDateLMove,     _bvSerialMasterFull.CurrentLoc, 
   _bvSerialMasterFull.CurrentAccLink,  _bvSerialMasterFull.StockCode,
   _bvSerialMasterFull.CurrentAccount,  _bvSerialMasterFull.CurrentLocationDesc,
   _bvSerialNumbersFull.SNTxDate,       _bvSerialNumbersFull.SNTxReference,
   _bvSerialNumbersFull.SNTrCodeID,     _bvSerialNumbersFull.SNTransType,
   _bvSerialNumbersFull.SNWarehouseID,  _bvSerialNumbersFull.TransAccount,
   _bvSerialNumbersFull.TransTypeDesc,  _bvSerialNumbersFull.SerialNumber AS Expr1,
   _bvSerialNumbersFull.SNStockLink AS Expr2, _bvSerialNumbersFull.WarehouseCode,
   _bvSerialNumbersFull.TrCode,        _bvSerialNumbersFull.CurrentLocationDesc AS Expr3,
   _bvSerialNumbersFull.CurrentAccount AS Expr5, 
   WhseMst.Name, _btblInvoiceLineSN.cSerialNumber, _btblInvoiceLines.fUnitPriceExcl,
   StkItem.Code, StkItem.AveUCst, StkItem.ItemGroup
FROM _btblInvoiceLineSN INNER 
JOIN _btblInvoiceLines ON _btblInvoiceLineSN.iSerialInvoiceLineID = _btblInvoiceLines.idInvoiceLines INNER 
JOIN _bvSerialMasterFull INNER 
JOIN _bvSerialNumbersFull ON _bvSerialMasterFull.SerialCounter = _bvSerialNumbersFull.SNLink INNER
JOIN WhseMst ON _bvSerialNumbersFull.SNWarehouseID = WhseMst.WhseLink
  ON _btblInvoiceLines.iStockCodeID = _bvSerialMasterFull.SNStockLink
 AND _btblInvoiceLineSN.cSerialNumber = _bvSerialMasterFull.SerialNumber INNER 
JOIN StkItem ON _bvSerialMasterFull.SNStockLink = StkItem.StockLink
WHERE _bvSerialNumbersFull.SNTransType = 8
  AND _bvSerialMasterFull.CurrentLoc   = 1
  AND StkItem.ItemGroup IN ('010', '020', '030', '040', '050', '060', 
                            '070', '080', '100', '150', '300', '400')
ORDER BY StkItem.ItemGroup, StkItem.Code, _bvSerialNumbersFull.SNTxDate

这样做基本上是获得某些项目的清单,并对它们进行老化分析。但是,系统连接到此数据库的方式有一些问题需要解决。此解决方案要求在此查询的结果数据集上对序列号进行计数,并为相应的串行记录添加该计数列。

现在计数位很简单,我写的一个解决方案是:

SELECT     _bvSerialMasterFull.SerialNumber, COUNT(_bvSerialMasterFull.SerialNumber) AS SerialCount
FROM         _btblInvoiceLineSN INNER JOIN
                      _btblInvoiceLines ON _btblInvoiceLineSN.iSerialInvoiceLineID = _btblInvoiceLines.idInvoiceLines INNER JOIN
                      _bvSerialMasterFull INNER JOIN
                      _bvSerialNumbersFull ON _bvSerialMasterFull.SerialCounter = _bvSerialNumbersFull.SNLink INNER JOIN
                      WhseMst ON _bvSerialNumbersFull.SNWarehouseID = WhseMst.WhseLink ON 
                      _btblInvoiceLines.iStockCodeID = _bvSerialMasterFull.SNStockLink AND 
                      _btblInvoiceLineSN.cSerialNumber = _bvSerialMasterFull.SerialNumber INNER JOIN
                      StkItem ON _bvSerialMasterFull.SNStockLink = StkItem.StockLink
WHERE     (_bvSerialNumbersFull.SNTransType = 8) AND (_bvSerialMasterFull.CurrentLoc = 1) AND (StkItem.ItemGroup IN ('010', '020', '030', '040', '050', '060', 
                      '070', '080', '100', '150', '300', '400'))
GROUP BY _bvSerialMasterFull.SerialNumber`

Thus, using an inner join with the original query we can have:
`SELECT     Cnt.SerialCount, _bvSerialMasterFull.SerialNumber, _bvSerialMasterFull.SNStockLink, _bvSerialMasterFull.SNDateLMove, _bvSerialMasterFull.CurrentLoc, 
                      _bvSerialMasterFull.CurrentAccLink, _bvSerialMasterFull.StockCode, _bvSerialMasterFull.CurrentAccount, _bvSerialMasterFull.CurrentLocationDesc, 
                      _bvSerialNumbersFull.SNTxDate, _bvSerialNumbersFull.SNTxReference, _bvSerialNumbersFull.SNTrCodeID, _bvSerialNumbersFull.SNTransType, 
                      _bvSerialNumbersFull.SNWarehouseID, _bvSerialNumbersFull.TransAccount, _bvSerialNumbersFull.TransTypeDesc, 
                      _bvSerialNumbersFull.SerialNumber AS Expr1, _bvSerialNumbersFull.SNStockLink AS Expr2, _bvSerialNumbersFull.WarehouseCode, 
                      _bvSerialNumbersFull.TrCode, _bvSerialNumbersFull.CurrentLocationDesc AS Expr3, _bvSerialNumbersFull.CurrentAccount AS Expr5, 
                      WhseMst.Name, _btblInvoiceLineSN.cSerialNumber, _btblInvoiceLines.fUnitPriceExcl, StkItem.Code, StkItem.AveUCst, StkItem.ItemGroup
FROM         _btblInvoiceLineSN INNER JOIN
                      _btblInvoiceLines ON _btblInvoiceLineSN.iSerialInvoiceLineID = _btblInvoiceLines.idInvoiceLines INNER JOIN
                      _bvSerialMasterFull INNER JOIN
                      _bvSerialNumbersFull ON _bvSerialMasterFull.SerialCounter = _bvSerialNumbersFull.SNLink INNER JOIN
                      WhseMst ON _bvSerialNumbersFull.SNWarehouseID = WhseMst.WhseLink ON 
                      _btblInvoiceLines.iStockCodeID = _bvSerialMasterFull.SNStockLink AND 
                      _btblInvoiceLineSN.cSerialNumber = _bvSerialMasterFull.SerialNumber INNER JOIN
                      StkItem ON _bvSerialMasterFull.SNStockLink = StkItem.StockLink
INNER JOIN (
            SELECT     _bvSerialMasterFull.SerialNumber, COUNT(_bvSerialMasterFull.SerialNumber) AS SerialCount
            FROM         _btblInvoiceLineSN INNER JOIN
                                  _btblInvoiceLines ON _btblInvoiceLineSN.iSerialInvoiceLineID = _btblInvoiceLines.idInvoiceLines INNER JOIN
                                  _bvSerialMasterFull INNER JOIN
                                  _bvSerialNumbersFull ON _bvSerialMasterFull.SerialCounter = _bvSerialNumbersFull.SNLink INNER JOIN
                                  WhseMst ON _bvSerialNumbersFull.SNWarehouseID = WhseMst.WhseLink ON 
                                  _btblInvoiceLines.iStockCodeID = _bvSerialMasterFull.SNStockLink AND 
                                  _btblInvoiceLineSN.cSerialNumber = _bvSerialMasterFull.SerialNumber INNER JOIN
                                  StkItem ON _bvSerialMasterFull.SNStockLink = StkItem.StockLink
            WHERE     (_bvSerialNumbersFull.SNTransType = 8) AND (_bvSerialMasterFull.CurrentLoc = 1) AND (StkItem.ItemGroup IN ('010', '020', '030', '040', '050', '060', 
                                  '070', '080', '100', '150', '300', '400'))
            GROUP BY _bvSerialMasterFull.SerialNumber
            ) Cnt ON Cnt.SerialNumber=_bvSerialMasterFull.SerialNumber
WHERE     (_bvSerialNumbersFull.SNTransType = 8) AND (_bvSerialMasterFull.CurrentLoc = 1) AND (StkItem.ItemGroup IN ('010', '020', '030', '040', '050', '060', 
                      '070', '080', '100', '150', '300', '400'))

但是,正如您所看到的,原始选择查询会运行两次并连接在一起。

我希望的是在原始查询中完成此操作而无需复制原始查询。可以这样做吗?如果是这样,我们非常感谢您的想法,输入和代码。

1 个答案:

答案 0 :(得分:0)

如果您使用的是sql server 2008或更高版本,则可以像这样在原始查询中添加计数:

COUNT(1) OVER(PARTITION BY _bvSerialMasterFull.SerialNumber)

不需要分组。