这是我在这里的第一篇文章。尽管我已经使用了几年了,但我仍然是SQL的新手。我正在尝试找到以下问题的解决方案,并正在寻找一些建议,请尽可能简单。
我有这个“ recordTable”,其中包含与交易相关的以下各列; “ personID”,“ recordID”,“ item”,“ txDate”和“ daySupply”。 recordID是主键。几乎每个personID都应具有许多不同的recordID和不同的txDate。
我的注意力集中在整个2017年的一个特定“项目”上。预计对于recordID,一旦项目daySupply过去了,我们将在此之前的5天和之后的某天之间看到该人的txDate较新的recordID。一天结束后的五天。
我要揭示的是在这十天的时间内没有预期的新recordID的不同recordID的数量。我认为这可能很简单,但是尝试创建查询存在很多困难,更不用说向某人解释了。
到目前为止,我的想法是创建两个临时表。第一个临时表存储与所需项目相关的所有记录,而我仅存储personID,recordID和txDate列。第二个临时表具有personID,recordID和txDate和daySupply的两个派生列;这些代表了之前的五天和之后的五天。
我正在尝试找到一种方法来确定第一个表中的RecordID的数量,这些记录在第二个表中没有期望对该personID的重新填充。我以为简单的EXCEPT可以做到这一点,但是我不认为有一种绕过递归类型语句来回答这个问题的方法,而且我从未对递归查询感到满意。
我搜索了Stackoverflow和其他地方,但无法给出答案。我真的很感谢一些更聪明的数据专家的帮助。这是到目前为止的代码。谢谢大家!
CREATE TABLE #temp1 (personID VARCHAR(20), recordID VARCHAR(10), txDate
DATE)
CREATE TABLE #temp2 (personID VARCHAR(20), recordID VARCHAR(10), startDate
DATE, endDate DATE)
INSERT INTO #temp1
SELECT [personID], [recordID], txDate
FROM recordTable
WHERE item = 'desiredItem'
AND txDate > '12/31/16'
AND txDate < '1/1/18';
INSERT INTO #temp2
SELECT [personID], [recordID], (txDate + (daySupply - 5)), (txDate +
(daySupply + 5))
FROM recordTable
WHERE item = 'desiredItem'
AND txDate > '12/31/16'
AND txDate < '1/1/18';
答案 0 :(得分:1)
我同意mypetlion的观点,即您本来可以更简洁地回答您的问题,但是我想我可以弄清楚您在问什么。
抢救SQL Window函数!
这是基本概念...
CREATE TABLE #fills(
personid INT,
recordid INT,
item NVARCHAR(MAX),
filldate DATE,
dayssupply INT
);
INSERT #fills
VALUES (1, 1, 'item', '1/1/2018', 30),
(1, 2, 'item', '2/1/2018', 30),
(1, 3, 'item', '3/1/2018', 30),
(1, 4, 'item', '5/1/2018', 30),
(1, 5, 'item', '6/1/2018', 30)
;
SELECT *,
ABS(
DATEDIFF(
DAY,
LAG(DATEADD(DAY, dayssupply, filldate)) OVER (PARTITION BY personid, item ORDER BY filldate),
filldate
)
) AS gap
FROM #fills
ORDER BY filldate;
...输出...
+----------+----------+------+------------+------------+------+
| personid | recordid | item | filldate | dayssupply | gap |
+----------+----------+------+------------+------------+------+
| 1 | 1 | item | 2018-01-01 | 30 | NULL |
| 1 | 2 | item | 2018-02-01 | 30 | 1 |
| 1 | 3 | item | 2018-03-01 | 30 | 2 |
| 1 | 4 | item | 2018-05-01 | 30 | 31 |
| 1 | 5 | item | 2018-06-01 | 30 | 1 |
+----------+----------+------+------------+------------+------+
您可以将结果插入到临时表中,仅提取所需的结果(间隙> 5),也可以将上面的查询用作CTE,并在没有临时表的情况下提取结果。
答案 1 :(得分:0)
可以这样表示:“给定一组订单,返回在预期的补货日期+/- 5天内(定义为txDate + DaysSupply)没有订单的子集。”
这可以简单地用NOT EXISTS解决。定义您要检查的订单范围,此查询将查找在预期补货日期(txDate + daysSupply)的任意5天之内没有补货订单(NOT EXISTS)的那些订单的子集。 >
SELECT
gappedOrder.personID
, gappedOrder.recordID
, gappedOrder.item
, gappedOrder.txDate
, gappedOrder.daysSupply
FROM
recordTable as gappedOrder
WHERE
gappedOrder.item = 'desiredItem'
AND gappedOrder.txDate > '12/31/16'
AND gappedOrder.txDate < '1/1/18'
--order not refilled within date range tolerance
AND NOT EXISTS
(
SELECT
1
FROM
recordTable AS refilledOrder
WHERE
refilledOrder.personID = gappedOrder.personID
AND refilledOrder.item = gappedOrder.item
--5 days prior to (txDate + daysSupply)
AND refilledOrder.txtDate >= DATEADD(day, -5, DATEADD(day, gappedOrder.daysSupply, gappedOrder.txDate))
--5 days after (txtDate + daysSupply)
AND refilledOrder.txtDate <= DATEADD(day, 5, DATEADD(day, gappedOrder.daysSupply, gappedOrder.txtDate))
);