具有下一个可能值最低的列(自连接 table)
Have a column with the lowest possible next value (self-joining a table)
我正在寻找一种方法来获取序列中的下一个最低值。基本上,我有一个日期数据集,我希望它在第二天成为 return,除非它是数据库中的最新日期,那么我希望它成为 return 这个。
我当前的查询看起来像这样并且几乎可以工作 - 当然直到我想要最新的可能值而不是下一个:
SELECT
a.date,
a.key,
a.description,
b.date NextDate
FROM
my_table a
CROSS APPLY (SELECT TOP 1
b.date
FROM
my_table b
WHERE
a.key = b.key AND
a.date < b.date) b
示例数据:
+----------+-----+-------------+
| date | key | description |
+----------+-----+-------------+
| 20170101 | atx | xxx |
| 20161228 | hfn | xxx |
| 20161222 | ktn | xxx |
| 20161214 | yqe | xxx |
| 20161204 | olp | xxx |
| 20161122 | bux | xxx |
+----------+-----+-------------+
结果应该是这样的:
+----------+-----+-------------+----------+
| date | key | description | NextDate |
+----------+-----+-------------+----------+
| 20170101 | atx | xxx | 20170101 |
| 20161228 | hfn | xxx | 20170101 |
| 20161222 | ktn | xxx | 20161228 |
| 20161214 | yqe | xxx | 20161222 |
| 20161204 | olp | xxx | 20161214 |
| 20161122 | bux | xxx | 20161204 |
+----------+-----+-------------+----------+
您可以使用 case
表达式来执行此操作。
SELECT
a.date,
a.key,
a.description,
case when date = max(a.date) over() then date
else (select min(date) from mytable b where a.date < b.date) end as NextDate
FROM
my_table a
您可以在日期列
上使用lag
select t.*,
lag(date, 1, date) over (order by date desc) nextdate
from
(SELECT
a.date,
a.key,
a.description,
b.date NextDate
FROM
my_table a
CROSS APPLY (SELECT TOP 1
b.date
FROM
my_table b
WHERE
a.key = b.key AND
a.date < b.date) b) t
我相信你想要:
select a.*,
coalesce(lead(date) over (order by date),
max(date) over ()
)
from my_table a;
试试这个
;with cte as
(
SELECT [DATE] = Cast([date] AS DATE),
[key],
[description],
Lag([date])OVER(ORDER BY Cast([date] AS DATE) DESC) AS prev_date
FROM ( VALUES ('20170101','atx','xxx'),
('20161228','hfn','xxx'),
('20161222','ktn','xxx'),
('20161214','yqe','xxx'),
('20161204','olp','xxx'),
('20161122','bux','xxx')) tc ([date], [key], [description])
)
SELECT [date],
[Key],
[Description],
NextDate = Iif([date] < prev_date, prev_date, [date])
FROM cte
结果:
+------------+-----+-------------+------------+
| date | Key | Description | NextDate |
+------------+-----+-------------+------------+
| 2017-01-01 | atx | xxx | 2017-01-01 |
| 2016-12-28 | hfn | xxx | 2017-01-01 |
| 2016-12-22 | ktn | xxx | 2016-12-28 |
| 2016-12-14 | yqe | xxx | 2016-12-22 |
| 2016-12-04 | olp | xxx | 2016-12-14 |
| 2016-11-22 | bux | xxx | 2016-12-04 |
+------------+-----+-------------+------------+
如果您的 table 从不缺少日期,则以下方法可行。
SELECT CONVERT(DATE,CONVERT(CHAR(10),a.date,120))
,a.key,
,a.description,
,CASE
WHEN (SELECT MAX(a.date) FROM my_table a) <> AsAtDateID
THEN DATEADD(DAY,1,CONVERT(DATE,CONVERT(CHAR(10),a.date,120)))--This could be a select statement
ELSE CONVERT(DATE,CONVERT(CHAR(10),a.date,120))
END
FROM my_table a
ORDER BY Date DESC
或者,如果缺少日期,那么您可以在 CASE 中使用 SQL 语句来获取下一个最高日期。
SELECT MIN(Date) FROM my_table WHERE Date > a.Date
不是最高性能的代码,但在我们谈论日期 table 时看到它会起作用。我相信 CTE 也可以用来做这件事,如果你需要更多的性能
使用 SQL 2008,不带 LEAD 和 LAG 等...
我正在寻找一种方法来获取序列中的下一个最低值。基本上,我有一个日期数据集,我希望它在第二天成为 return,除非它是数据库中的最新日期,那么我希望它成为 return 这个。
我当前的查询看起来像这样并且几乎可以工作 - 当然直到我想要最新的可能值而不是下一个:
SELECT
a.date,
a.key,
a.description,
b.date NextDate
FROM
my_table a
CROSS APPLY (SELECT TOP 1
b.date
FROM
my_table b
WHERE
a.key = b.key AND
a.date < b.date) b
示例数据:
+----------+-----+-------------+
| date | key | description |
+----------+-----+-------------+
| 20170101 | atx | xxx |
| 20161228 | hfn | xxx |
| 20161222 | ktn | xxx |
| 20161214 | yqe | xxx |
| 20161204 | olp | xxx |
| 20161122 | bux | xxx |
+----------+-----+-------------+
结果应该是这样的:
+----------+-----+-------------+----------+
| date | key | description | NextDate |
+----------+-----+-------------+----------+
| 20170101 | atx | xxx | 20170101 |
| 20161228 | hfn | xxx | 20170101 |
| 20161222 | ktn | xxx | 20161228 |
| 20161214 | yqe | xxx | 20161222 |
| 20161204 | olp | xxx | 20161214 |
| 20161122 | bux | xxx | 20161204 |
+----------+-----+-------------+----------+
您可以使用 case
表达式来执行此操作。
SELECT
a.date,
a.key,
a.description,
case when date = max(a.date) over() then date
else (select min(date) from mytable b where a.date < b.date) end as NextDate
FROM
my_table a
您可以在日期列
上使用lag
select t.*,
lag(date, 1, date) over (order by date desc) nextdate
from
(SELECT
a.date,
a.key,
a.description,
b.date NextDate
FROM
my_table a
CROSS APPLY (SELECT TOP 1
b.date
FROM
my_table b
WHERE
a.key = b.key AND
a.date < b.date) b) t
我相信你想要:
select a.*,
coalesce(lead(date) over (order by date),
max(date) over ()
)
from my_table a;
试试这个
;with cte as
(
SELECT [DATE] = Cast([date] AS DATE),
[key],
[description],
Lag([date])OVER(ORDER BY Cast([date] AS DATE) DESC) AS prev_date
FROM ( VALUES ('20170101','atx','xxx'),
('20161228','hfn','xxx'),
('20161222','ktn','xxx'),
('20161214','yqe','xxx'),
('20161204','olp','xxx'),
('20161122','bux','xxx')) tc ([date], [key], [description])
)
SELECT [date],
[Key],
[Description],
NextDate = Iif([date] < prev_date, prev_date, [date])
FROM cte
结果:
+------------+-----+-------------+------------+
| date | Key | Description | NextDate |
+------------+-----+-------------+------------+
| 2017-01-01 | atx | xxx | 2017-01-01 |
| 2016-12-28 | hfn | xxx | 2017-01-01 |
| 2016-12-22 | ktn | xxx | 2016-12-28 |
| 2016-12-14 | yqe | xxx | 2016-12-22 |
| 2016-12-04 | olp | xxx | 2016-12-14 |
| 2016-11-22 | bux | xxx | 2016-12-04 |
+------------+-----+-------------+------------+
如果您的 table 从不缺少日期,则以下方法可行。
SELECT CONVERT(DATE,CONVERT(CHAR(10),a.date,120))
,a.key,
,a.description,
,CASE
WHEN (SELECT MAX(a.date) FROM my_table a) <> AsAtDateID
THEN DATEADD(DAY,1,CONVERT(DATE,CONVERT(CHAR(10),a.date,120)))--This could be a select statement
ELSE CONVERT(DATE,CONVERT(CHAR(10),a.date,120))
END
FROM my_table a
ORDER BY Date DESC
或者,如果缺少日期,那么您可以在 CASE 中使用 SQL 语句来获取下一个最高日期。
SELECT MIN(Date) FROM my_table WHERE Date > a.Date
不是最高性能的代码,但在我们谈论日期 table 时看到它会起作用。我相信 CTE 也可以用来做这件事,如果你需要更多的性能 使用 SQL 2008,不带 LEAD 和 LAG 等...