为了举例,我有以下数据集: ToyReferenceNumber ,公司, CompositeCalculatedField , PermanentRecallDate , ReturnToStoreDate
基本上,每个项目可能有3-4个条目(想象公司TheToyCompany或TTC):
TTC-011-0934, TTC, calculation, NULL, 2017-03-01 12:01:01.00
TTC-011-0934, TTC, calculation, NULL, 2014-05-01 12:01:01.00
TTC-011-0934, TTC, calculation, NULL, 2011-08-27 12:01:01.00
TTC-994-0132, TTC, calculation, 2017-06-12 12:01:01.00, NULL
TTC-994-0132, TTC, calculation, NULL, 2017-02-01 12:01:01.00
TTC-354-0122, TTC, calculation, NULL, 2015-03-01 12:01:01.00
TTC-354-0122, TTC, calculation, NULL, NULL
从业务逻辑的角度来看,对于第一个产品(0934),它有多次召回(打印或生产批次,我们不在乎),但是已经修复并在每次产品之后返回到商店。
对于0132,它试图修复缺陷,但随后该公司决定废弃该产品,因为它还没有销售。
对于0122,产品批次被召回,修复,然后在2015-03-01发送到商店,但当前批次当前正在修复(因此,NULL,NULL)。
管理层想要的是一份报告,显示当前的修理工厂结算(例如修理玩具的人员的时间表)。
伪查询:
For a given product, return only the record with NULL, NULL dates (actively being fixed)
IF not null, null, return only the record with the PermanentRecallDate
IF no PermanentRecallDate, return only the record with the latest ReturnToStoreDate
oracle查询与以下伪代码基本相同:
SELECT <normal columns>
,MAX(ts.PermanentRecallDate) KEEP (dense_rank last order by ts.PermanentRecallDate NULLS LAST) PERANENTRECALLDATE
,MAX(ts.ReturnToStoreDate) KEEP (dense_rank last order by ts.ReturnToStoreDate NULLS LAST) RETURNTOSTOREDATE
oracle查询非常简单,但我需要在T-SQL中使用它:
WITH CTE_ToyReferenceExport
AS
(
SELECT ts.ToyReferenceNumber AS TOYNUM
,tsh.Company AS COMPANY
,MAX(largeSetofCalculations) AS CompositeCalculatedField
,MAX(ts.PermanentRecallDate) AS PERMANETRECALL
,MAX(ts.ReturnToStoreDate) AS RETURNTOSTORE
,DENSE_RANK() OVER (PARTITION BY ts.ToyReferenceNumber ORDER BY ts.PermanentRecallDate) as PRDRank
,DENSE_RANK() OVER (PARTITION BY ts.ToyReferenceNumber ORDER BY ts.(ReturnToStoreDate) AS RTSDRank
FROM origin.ToyStaging ts
JOIN origin.ToyOrders to ON ts.ordernumer = to.ordno
JOIN origin.ToyShipment tsh ON to.packno = tsh.crateno
LEFT JOIN origin.Shippers sh ON to.packno = sh.cratenum AND 'calcField' = sh.originfield
GROUP BY ts.ToyReferenceNumber, tsh.Company, ts.permanentrecalldate, ts.returntostoredate
)
还有更多内容,但让我感到震惊的主要事情是获取“MAX..Keep Dense_rank最后一个订单由... NULLS LAST”逻辑返回的结果集。
任何帮助将不胜感激。 SQL Server 2012是版本。
答案 0 :(得分:0)
如果我理解正确,如果没有NULL
,则需要最长日期;如果至少有NULL
,则需要SELECT <normal columns>,
(CASE WHEN COUNT(*) <> COUNT(ts.PermanentRecallDate) THEN NULL
ELSE MAX(ts.PermanentRecallDate)
END) as PERANENTRECALLDATE,
(CASE WHEN COUNT(*) <> COUNT(ts.ReturnToStoreDate) THEN NULL
ELSE MAX(ts.ReturnToStoreDate)
END) as RETURNTOSTOREDATE
。如果这是对的:
{{1}}
答案 1 :(得分:0)
这是实现您的要求的一种方法。
WITH Limits AS (
SELECT DISTINCT ToyReferenceNumber
, FIRST_VALUE(PermanentRecallDate)
OVER (PARTITION BY ToyReferenceNumber
ORDER BY CASE WHEN ReturnToStoreDate IS NULL THEN 1 ELSE 2 END
, CASE WHEN PermanentRecallDate IS NULL THEN 1 ELSE 2 END
, PermanentRecallDate DESC) PermanentRecallDate
, FIRST_VALUE(ReturnToStoreDate)
OVER (PARTITION BY ToyReferenceNumber
ORDER BY CASE WHEN ReturnToStoreDate IS NULL THEN 1 ELSE 2 END
, ReturnToStoreDate DESC) ReturnToStoreDate
FROM ToyStaging
)
SELECT ts.*
FROM ToyStaging TS
JOIN Limits L
ON TS.ToyReferenceNumber = L.ToyReferenceNumber
AND (L.PermanentRecallDate IS NULL
and ts.PermanentRecallDate is null
OR TS.PermanentRecallDate = L.PermanentRecallDate)
AND (L.ReturnToStoreDate IS NULL
AND ts.ReturnToStoreDate is null
OR TS.ReturnToStoreDate = L.ReturnToStoreDate)
在Limits
CTE中,如果给定FIRST_VALUE
存在null空记录,则ToyReferenceNumber
分析函数都将返回null。否则,PermanentRecallDate
列将返回最新的PermanentRecallDate
,ReturnToStoreDate
列将在不存在ReturnToStoreDate
时返回最新的PermanentRecallDate
,从而实例化您的规则记录返回。不同的剪辑会删除重复的记录,然后将Limits
连接回ToyStaging
以获取所需的数据。
根据您的样本数据,限制CTE返回:
| ToyReferenceNumber | PermanentRecallDate | ReturnToStoreDate |
|--------------------|------------------------|------------------------|
| TTC-011-0934 | (null) | 2017-03-01 12:01:01.00 |
| TTC-354-0122 | (null) | (null) |
| TTC-994-0132 | 2017-06-12 12:01:01.00 | (null) |
并且整个查询返回:
| ToyReferenceNumber | Company | CompositeCalculatedField | PermanentRecallDate | ReturnToStoreDate |
|--------------------|---------|--------------------------|------------------------|------------------------|
| TTC-011-0934 | TTC | calculation | (null) | 2017-03-01 12:01:01.00 |
| TTC-354-0122 | TTC | calculation | (null) | (null) |
| TTC-994-0132 | TTC | calculation | 2017-06-12 12:01:01.00 | (null) |
请参阅此SQL Fiddle以查看其实际效果。