我需要返回按reference3
分组的最后一个寄售编号(仅当有超过1条记录且具有相同的reference3
时。
有没有办法使用partition by
命令创建下面的查询?我做了一次尝试:
尝试使用分区:(不起作用:/)
SELECT
SubAccountId,
Reference3,
ConsignmentNumber,
MAX(ConsignmentNumber) OVER(PARTITION BY SubAccountId, Reference3) AS LastConsignmentNumber
FROM [CxGen].[dbo].[consignment] c
GROUP BY SubAccountId, Reference3
HAVING COUNT(*) > 1
原始查询:
;WITH DuplicatedConsignments AS
(
SELECT Reference3,
SubAccountId,
Max(ConsignmentDate) AS ConsignmentDate
FROM [CxGen].[dbo].[consignment]
WHERE Reference3 IN
(
SELECT Reference3
FROM [CxGen].[dbo].[Consignment]
GROUP BY Reference3, SubAccountId
HAVING Count(Reference3) > 1
)
GROUP BY Reference3, SubAccountId
)
SELECT C.SubAccountid,
C.ConsignmentDate,
C.Reference3,
C.ConsignmentNumber,
C.CreatedOn
FROM [CxGen].[dbo].[consignment] C
INNER JOIN DuplicatedConsignments dc
ON C.reference3 = dc.reference3
AND C.consignmentdate = dc.consignmentdate
AND C.subaccountid = dc.subaccountid
WHERE C.ConsignmentDate > GETDATE()-1
ORDER BY C.Reference3,
C.SubaccountId,
C.ConsignmentNumber
预期结果:
+--------------+-----------------+------------+-------------------+-----------------+
| SubAccountid | ConsignmentDate | Reference3 | ConsignmentNumber | CreatedOn |
+--------------+-----------------+------------+-------------------+-----------------+
| 2070 | 7/09/2017 14:09 | 1279152 | DNZ0322457 | 7/09/2017 14:09 |
| 1065 | 7/09/2017 15:42 | 1647907 | AULGP00031023 | 7/09/2017 15:42 |
| 1065 | 7/09/2017 9:30 | 1653615 | AULGP00031009 | 7/09/2017 9:30 |
| 1085 | 6/09/2017 16:52 | 1661307 | 6X31222878 | 6/09/2017 16:52 |
| 1085 | 6/09/2017 16:52 | 1661308 | 6X31222877 | 6/09/2017 16:52 |
| 1085 | 6/09/2017 16:40 | 1661311 | 6X31222871 | 6/09/2017 16:40 |
| 1085 | 6/09/2017 16:30 | 1661312 | 6X31222853 | 6/09/2017 16:30 |
| 1085 | 6/09/2017 16:56 | 1661318 | 6X31222879 | 6/09/2017 16:56 |
| 1085 | 6/09/2017 16:41 | 1661320 | 6X31222872 | 6/09/2017 16:41 |
| 1085 | 6/09/2017 16:42 | 1661321 | 6X31222873 | 6/09/2017 16:42 |
| 1085 | 6/09/2017 16:43 | 1661322 | 6X31222874 | 6/09/2017 16:43 |
| 1085 | 6/09/2017 17:11 | 1661323 | IA0017426243 | 6/09/2017 17:11 |
| 1085 | 6/09/2017 16:44 | 1661324 | ia0017426030 | 6/09/2017 16:44 |
| 1085 | 6/09/2017 16:51 | 1661325 | 6X31222876 | 6/09/2017 16:51 |
| 1085 | 6/09/2017 16:51 | 1661326 | ia0017426031 | 6/09/2017 16:51 |
| 1085 | 6/09/2017 16:55 | 1661352 | IA0017426032 | 6/09/2017 16:55 |
| 1085 | 7/09/2017 16:21 | 1661440 | IA0017426261 | 7/09/2017 16:21 |
| 2060 | 7/09/2017 15:56 | 1662227 | 2.3601E+12 | 7/09/2017 15:56 |
| 2060 | 7/09/2017 15:49 | 1663004 | NULL | 7/09/2017 15:49 |
+--------------+-----------------+------------+-------------------+-----------------+
答案 0 :(得分:1)
如果您要查找分区的最后一个值,则应使用LAST_VALUE
代替MAX
:
LASTVALUE(ConsignmentNumber)
OVER
(PARTITION BY SubAccountId, Reference3 ORDER By youOrderCol) AS LastConsignmentNumber
您还需要指定一个确定每个分区内顺序的字段。在ORDER BY
子句中的OVER
中使用此字段。
您的查询可能如下所示:
;With LastValCTE AS (
SELECT SubAccountId,
Reference3,
LASTVALUE(ConsignmentNumber)
OVER
(PARTITION BY SubAccountId, Reference3
ORDER By youOrderCol) AS LastConsignmentNumber
FROM [CxGen].[dbo].[consignment]
)
SELECT DISTINCT
c1.SubAccountId,
c1.Reference3,
c2.LastConsignmentNumber
FROM [CxGen].[dbo].[consignment] AS c1
JOIN LastValCTE AS c2
ON c1.SubAccountId = c2.SubAccountId AND c1.Reference3 = c2.Reference3
GROUP BY c1.SubAccountId, c1.Reference3
HAVING COUNT(*) > 1
此查询返回每个(SubAccountId, Reference3)
组的最后一个值。为每个组返回一条记录。过滤掉只有一条记录的组。
如果您想获取每个组的所有记录,那么您可以使用以下查询:
;With LastValCTE AS (
SELECT SubAccountId,
Reference3,
ConsignmentNumber,
COUNT(*) OVER (PARTITION BY SubAccountId, Reference3) AS cnt,
LASTVALUE(ConsignmentNumber)
OVER
(PARTITION BY SubAccountId, Reference3
ORDER By youOrderCol) AS LastConsignmentNumber
FROM [CxGen].[dbo].[consignment]
)
SELECT SubAccountId,
Reference3,
ConsignmentNumber,
LastConsignmentNumber
FROM LastValCTE
WHERE cnt > 1
答案 1 :(得分:0)
我会按如下方式对您的查询进行短语。迭代表中的每个帐户/参考组,并为每个记录分配计数和密集排名。然后只保留计数超过1且密集等级为1的记录。
SELECT
t.SubAccountId,
t.Reference3,
t.ConsignmentNumber
FROM
(
SELECT
SubAccountId,
Reference3,
ConsignmentNumber,
COUNT(*) OVER (PARITION BY SubAccountId, Reference3) cnt,
DENSE_RANK() OVER(PARTITION BY SubAccountId, Reference3) AS dr
FROM [CxGen].[dbo].[consignment] c
) t
WHERE
t.cnt > 1 AND t.dr = 1;