2017-02-21 11 views
0

В в Microsoft SQL Server, мы эта таблица, которая регистрирует изменения свойств пользователей:SQL: Найти совпадение даты за пределами или в пределах

ID | userID | prop | changeDate 
------------------------------- 
4 23  B  2017-02-18 
1 14  D  2013-05-19 
2 15  C  2014-04-10 
3 23  A  2016-01-11 

То, что я хотел бы сделать это, чтобы запросить эту таблицу и найти активное свойство в диапазоне дат.

Например период 2016-08-01 к 2017-01-01 Я хотел бы получить userID 23 с опорой A потому, что был активным свойство для этого пользователя, пока он не был изменен на 2017-02-18

Я начал с changeDate BETWEEN '2016-08-01' and '2017-01-01' но только чехлы в тех случаях, когда у меня есть точная дата начала.

Я немного схожу с ума. Этот квест возможен даже с этими данными? Или, может быть, я задаю неправильный вопрос?

+2

Я думаю, что вы просите неправильный вопрос. Что вы хотите вернуть, если пользователь имеет несколько свойств в течение периода. –

+0

Это хороший момент, Гордон. Я упростил эту часть. – teni

ответ

1

Самостоятельно присоединиться может помочь здесь.

CREATE TABLE x (ID INT, userID INT, prop CHAR(1), changeDate DATETIME) 

INSERT INTO x 
    VALUES (4, 23, 'B', '20170218'), 
     (1, 14, 'D', '20130519'), 
     (2, 15, 'C', '20140410'), 
     (3, 23, 'A', '20160111') 

; WITH cte AS (
    SELECT x1.userID, x1.prop, x1.changeDate AS StartDate, MIN(x2.changeDate) AS ExitDate 
    FROM x x1 
      LEFT OUTER JOIN x x2 
        ON x1.changeDate < x2.changeDate 
    GROUP BY x1.userID, x1.prop, x1.changeDate 
) 

SELECT * 
FROM cte 
WHERE Startdate > = '20160801' 
    AND (ExitDate IS NULL OR ExitDate < '20170101') 

Это дает вам то, что вы ищете

userID | prop | StartDate    | ExitDate 
-------------------------------------------------- 
23  B  2017-02-18 00:00:00.000 NULL  
+0

Отлично. Это потрясающе! Спасибо огромное! Я бы сгруппировал по changeDate, userID, prop. Но кроме этого это действительно сделало мой вечер :) – teni

2

Для таблицы этого типа типичный вопрос: «Каким было заданное свойство пользователя как определенная дата?»

Это отвечает на этот вопрос:

select pc.* 
from (select pc.*, 
      row_number() over (partition by userId order by changeDate desc) as seqnum 
     from propertychanges pc 
     where changeDate <= @AsOfDate 
    ) pc 
where seqnum = 1; 
+0

Спасибо, что предложили как вопрос, так и ответ;) Я некоторое время был потерян. Однако в этом случае ключ даты является ключевым. Таким образом, типичный вопрос не совсем подходит. – teni