[英]SQL - Identify consecutive numbers in a table
Is there a way to flag consecutive numbers in an SQL table? 有没有办法标记SQL表中的连续数字?
Based on the values in 'value_group_4' column, is it possible to tag continous values? 根据“ value_group_4”列中的值,是否可以标记连续值? This needs to be done within groups of each 'date_group_1'
这需要在每个“ date_group_1”的组内完成
I tried using row_numbers, rank, dense_rank but unable to come up with a foolproof way. 我尝试使用row_numbers,rank,densed_rank,但无法提出一种万无一失的方法。
This has nothing to do with consecutiveness. 这与连续性无关。 You simply want to mark all rows where date_group_1 and value_group_4 are not unique.
您只想标记date_group_1和value_group_4不唯一的所有行。
One way: 单程:
select
mytable.*,
case when exists
(
select null
from mytable agg
where agg.date_group_1 = mytable.date_group_1
and agg.value_group_4 = mytable.value_group_4
group by agg.date_group_1, agg.value_group_4
having count(*) > 1
) then 1 else 0 end as flag
from mytable
order by date_group_1, value_group_4;
In a later version of SQL Server you'd use COUNT OVER
instead. 在更高版本的SQL Server中,您将改用
COUNT OVER
。
If your version of SQL Server doesn't have a full suite of windowing functions it should be still possible. 如果您的SQL Server版本没有全套的窗口功能,则应该仍然可以。 This problem looks like a last-non-null problem which Itzik Ben-Gan has good example here... http://www.itprotoday.com/software-development/last-non-null-puzzle
这个问题看起来像一个last-non-null问题,Itzik Ben-Gan在这里有个很好的例子... http://www.itprotoday.com/software-development/last-non-null-puzzle
Also, look at Mikael Eriksson's answer here which uses no windowing functions. 另外,在这里查看Mikael Eriksson的答案,该答案不使用窗口功能。
SQL tables represent unordered sets. SQL表表示无序集。 There is no such thing as consecutive values, unless a column specifies the ordering.
除非有列指定顺序,否则没有连续值之类的东西。 Your data does not have such an obvious column, but I'll assume one exists and just call it
id
for convenience. 您的数据没有如此明显的列,但我假设其中存在一个,为方便起见仅将其称为
id
。
With such a column, lag()
/ lead()
does what you want: 使用这样的列,
lag()
/ lead()
可以满足您的需求:
select t.*,
(case when lag(value_group_4) over (partition by data_group1 order by id) = value_group_4
then 1
when lead(value_group_4) over (partition by data_group1 order by id) = value_group_4
then 1
else 0
end) as flag
from t;
On close inspection, value_group_3
may do what you want. 经过仔细检查,
value_group_3
可能会做您想要的。 So you can use that for the id
. 因此,您可以将其用作
id
。
If the order of your data is determined by the date_group_1
, value_group_3
column values, then why not make it as simple as the following query: 如果您的数据顺序是由
date_group_1
, value_group_3
列值确定的,那么为什么不像以下查询一样简单:
select
*,
rank() over(partition by date_group_1 order by value_group_3) - 1 value_group_3,
case
when count(*) over(partition by date_group_1, value_group_3) > 1 then 1
else 0
end expected_result
from data;
Output: 输出:
| date_group_1 | category_group_2 | value_group_3 | value_group_3 | expected_result |
+--------------+------------------+---------------+---------------+-----------------+
| 2018-01-11 | A | 15.3 | 0 | 0 |
| 2018-01-11 | B | 17.3 | 1 | 1 |
| 2018-01-11 | A | 17.3 | 1 | 1 |
| 2018-01-11 | B | 21 | 3 | 0 |
| 2018-01-22 | A | 15.3 | 0 | 0 |
| 2018-01-22 | B | 17.3 | 1 | 0 |
| 2018-01-22 | A | 21 | 2 | 0 |
| 2018-01-22 | B | 23 | 3 | 0 |
| 2018-03-13 | A | 15.3 | 0 | 0 |
| 2018-03-13 | B | 17.3 | 1 | 1 |
| 2018-03-13 | A | 17.3 | 1 | 1 |
| 2018-03-13 | B | 23 | 3 | 0 |
| 2018-05-15 | A | 6 | 0 | 0 |
| 2018-05-15 | B | 6.3 | 1 | 0 |
| 2018-05-15 | A | 15 | 2 | 0 |
| 2018-05-15 | B | 16.3 | 3 | 1 |
| 2018-05-15 | A | 16.3 | 3 | 1 |
| 2018-05-15 | B | 22 | 5 | 0 |
| 2019-05-04 | A | 0 | 0 | 0 |
| 2019-05-04 | B | 7 | 1 | 0 |
| 2019-05-04 | A | 15.3 | 2 | 0 |
| 2019-05-04 | B | 17.3 | 3 | 0 |
Test it online with SQL Fiddle . 使用SQL Fiddle在线进行测试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.