什么样的查询支持在排行行时考虑我的行的顺序和它们中的数据范围?数据应按标识顺序处理,我希望范围边界定义为[Time] > 2 or [Time] < -2
。
编辑:换句话说,我想将行视为列表并将它们分成列表,其中ParitionId是行列表的索引。
编辑2:我忘了清楚每当[时间]值超出所需范围时,分区ID应该加1。此要求意味着我们不能使用GROUP BY
使用CREATE TABLE foobartable
([ID] int Identity(1,1) NOT NULL, [Time] float, [X] float, [Y] float)
;
INSERT INTO foobartable
([Time], [X], [Y])
VALUES
(0.0, 1, 1),
(1.0, 1, 1),
(2.0, 1, 1),
(3.0, 1, 1),
(2.0, 1, 1),
(1.0, 1, 1),
(-1.0, 1, 1),
(-2.0, 1, 1),
(-3.0, 1, 1),
(-2.0, 1, 1),
(-1.0, 1, 1),
(0.0, 1, 1),
(1.0, 1, 1),
(2.0, 1, 1),
(3.0, 1, 1),
(2.0, 1, 1)
;
来填充行,如果[时间]落在范围内或外部,则返回true或false。
MS SQL Server 2014架构设置:
| Id | PartitionId |
|----|-------------|
| 1 | 0 |
| 2 | 0 |
| 3 | 0 |
| 4 | 1 |
| 5 | 2 |
| 6 | 2 |
| 7 | 2 |
| 8 | 2 |
| 9 | 3 |
| 10 | 4 |
| 11 | 4 |
| 12 | 4 |
| 13 | 4 |
| 14 | 4 |
| 15 | 5 |
| 16 | 6 |
期望的结果
ScriptParser sp = new ScriptParser();
StatementContext sc = sp.statement();
答案 0 :(得分:1)
我认为你可以使用Recursive CTE。像这样:
WITH cte AS
(
SELECT *, row_number() over(ORDER BY ID) rn
FROM #foobartable
),
cte2 as
(
SELECT cast(0 AS int) AS rn, NULL AS id,
cast(NULL AS float) AS time,
cast(NULL AS float) AS x,
cast(NULL AS float) AS y,
0 AS p
UNION all
SELECT cast(cte.rn AS int), cte.id,
cte.[Time], cte.x, cte.y,
iif(
cte2.time <= 2.0 AND cte.time > 2.0 OR
cte2.time > 2.0 AND cte.time <= 2.0 OR
cte2.time >= -2.0 AND cte.time < -2.0 OR
cte2.time < -2.0 AND cte.time >= -2.0
,p + 1
,p
) AS p
FROM cte2
JOIN cte ON cte2.rn + 1 = cte.rn
)
SELECT id, p AS PartitionId
FROM cte2
WHERE id IS NOT NULL
ORDER BY id;
输出:
id PartitionId
----------- -----------
1 0
2 0
3 0
4 1
5 2
6 2
7 2
8 2
9 3
10 4
11 4
12 4
13 4
14 4
15 5
16 6
答案 1 :(得分:1)
我提出的解决方案:
MS SQL Server 2014架构设置:
CREATE TABLE foobartable
([ID] int Identity(1,1) NOT NULL, [Time] float, [X] float, [Y] float)
;
INSERT INTO foobartable
([Time], [X], [Y])
VALUES
(0.0, 1, 1),
(1.0, 1, 1),
(2.0, 1, 1),
(3.0, 1, 1),
(2.0, 1, 1),
(1.0, 1, 1),
(-1.0, 1, 1),
(-2.0, 1, 1),
(-3.0, 1, 1),
(-2.0, 1, 1),
(-1.0, 1, 1),
(0.0, 1, 1),
(1.0, 1, 1),
(2.0, 1, 1),
(3.0, 1, 1),
(2.0, 1, 1)
;
查询1 :
with pairs as (
select
t1.[ID] as [ID1],
t2.[ID] as [ID2]
from foobartable as t1
left outer join foobartable as t2 on (t1.[ID] + 1) = t2.[ID]
),
loop ([ID], [Level])
as (
select top 1
t.[ID],
0
from foobartable as t
union all
select
p.[ID2],
(case when (case when t1.[Time] > 2 or t1.[Time] < -2 then 0 else 1 end) <> (case when t2.[Time] > 2 or t2.[Time] < -2 then 0 else 1 end) then [Level] + 1 else [Level] end) as [Level]
from loop
inner join pairs as p on p.[ID1] = loop.[ID]
inner join foobartable as t1 on p.[ID1] = t1.[ID]
inner join foobartable as t2 on p.[ID2] = t2.[ID]
)
select [Id], [Level] as [PartitionId] from loop
<强> Results 强>:
| Id | PartitionId |
|----|-------------|
| 1 | 0 |
| 2 | 0 |
| 3 | 0 |
| 4 | 1 |
| 5 | 2 |
| 6 | 2 |
| 7 | 2 |
| 8 | 2 |
| 9 | 3 |
| 10 | 4 |
| 11 | 4 |
| 12 | 4 |
| 13 | 4 |
| 14 | 4 |
| 15 | 5 |
| 16 | 6 |