如何获取具有最大值的行并且它与另外两个表匹配?

时间:2017-09-08 08:06:36

标签: sql sql-server

由于某些原因,我的客户没有跟踪他的商店发生了什么,他做的是计算他每次都有的产品,一些产品每天其他每周和一些月,无论如何我有三个表看起来像这样< / p>

PRODUCT
------------------
| idPro | ProName|
------------------
|  1    | P1     |
|  2    | P2     |
|  3    | P3     |
------------------

STOCK
-------------------------
| idPro | idCount | Qty |
-------------------------
|   1   |   1     | 10  |
|   2   |   2     | 30  |
|   1   |   4     | 60  |
|   2   |   5     | 10  |
-------------------------

Count
------------------
| idCount | Date |
------------------
|  1      | 1100 |
|  2      | 1109 |
|  3      | 1505 |
|  4      | 1806 |
------------------

我想得到一个产品和数量的最后一次计数,换句话说我想让产品暂停计数(我检查最后的计数是否超过一周或从未计算过)喜欢

----------------------------
|ProName | LastCount | Qty |
----------------------------
|  1     | 1505      | 60  |
|  2     | 1806      | 10  |
|  3     | NULL      | NULL|
----------------------------

我想出的是这个

USE StoTrackerBasic
GO

SELECT P.ProCode, P.ProName, MAX(R.CountDate) LastCount
    FROM Product P 
    LEFT JOIN Stock as S ON P.idProduct = S.idProduct
    INNER JOIN Count R ON R.idCount = S.idCount
    --  WHERE R.CountDate > 100 OR R.CountDate IS NULL
GROUP BY P.ProName, P.ProCode
ORDER BY P.ProName

但无法添加Qty

此外,我想重要的是要提到表PRODUCT可能有超过1000个产品,COUNT表可能有三倍,因为客户可能每天执行涉及不同产品的3或10个计数,所以我的查询我想检查Count表上每一行的每一个产品。

PS 表上的日期计数是时间戳

3 个答案:

答案 0 :(得分:6)

您可以使用“外部申请”收集最后一个相关项目。

DECLARE @Product TABLE ( idProduct INT , ProName VARCHAR(50) )
INSERT INTO @Product VALUES( 1, 'P1'), (2, 'P2'), (3, 'P3')

DECLARE @Stock TABLE ( idProduct INT,  idCount INT,  Qty INT )
INSERT INTO @Stock VALUES (1, 1, 10), (2, 2, 30), (1, 4, 60), (2, 5,10)

DECLARE @Count TABLE ( idCount INT , CountDate VARCHAR(20) )
INSERT INTO @Count  VALUES (1, 1100), (2, 1109), (3, 1505), (4, 1806)

SELECT  P.idProduct ProID, P.ProName, A.CountDate LastCount, A.Qty LastQty
FROM @Product P 
OUTER APPLY(    
        SELECT TOP 1 R.CountDate, S.Qty 
        FROM 
            @Stock as S 
            INNER JOIN @Count R ON R.idCount = S.idCount
        WHERE 
            P.idProduct = S.idProduct
        ORDER BY 
            R.CountDate DESC
        ) AS A
ORDER BY P.ProName

如果Stock表有多个记录,那么应该根据优先级将谓词的附加顺序添加到外部查询中。

答案 1 :(得分:2)

;WITH cteRowRum (rowNum,idPro,idCount,Qty) AS(
    Select row_number()over(Order by idCount) as rowNum,idPro,idCount,Qty
    From Stock)

Select C.idPro,B.Date,A.Qty
From ProductTBl as C
Left Join
(
    Select *
    From
    (
        Select *, row_Number()Over(Partition by idPro Order by rowNum desc) as SelectedRows
        From cteRowRum
    ) as A
    Where SelectedRows = 1
) as A
On C.idPro = A.idPro
Left Join
CountTbl as B
On A.rowNum=B.idCount

答案 2 :(得分:-1)

在我看来,使用GROUP BY子句是不必要且有问题的,您可以使用子查询来选择最后的计数日期。另外,为了消除混淆,首先处理Stock和Count之间的INNER JOIN(参见括号的使用),然后选择RIGHT JOIN with Products

USE StoTrackerBasic
GO

SELECT P.idPro, P.ProName, R.CountDate AS LastCount, S.Qty
    FROM (Stock as S INNER JOIN (
        SELECT TOP 1 * FROM Count ORDER BY CountDate DESC
    ) R ON R.idCount = S.idCount)
    RIGHT JOIN Product P 
      ON S.idProduct = P.idProduct
GROUP BY P.ProName, P.ProCode
ORDER BY P.ProName