T-SQL-按时间顺序查找记录

时间:2018-11-02 21:29:31

标签: sql-server tsql

这是我在这里的第一篇文章。尽管我已经使用了几年了,但我仍然是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';

2 个答案:

答案 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))
    );