简体   繁体   English

SQL-识别表格中的连续数字

[英]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_1value_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM