SQL: 如何动态解析从最小到下一分钟的范围?
SQL: How do dynamically parse ranges from min to next min?
我想弄清楚如何(或看看是否可能)我可以获取 'TEST' 的最小值并获取 'TEST' 的下一个最小值,然后再次加入并继续第二个最小值,等等,等等
表 1
ID TEST
A12 1
A12 2
A12 3
A12 5
A12 8
B35 1
B35 3
我想要的结果:
ID RANGE1 RANGE2
A12 1 2
A12 2 3
A12 3 5
A12 5 8
B35 1 3
table 我使用的代码:
WITH FRED AS
(
SELECT 'A12' AS ID
, 1 AS TEST
UNION
SELECT 'A12' AS ID
, 2 AS TEST
UNION
SELECT 'A12' AS ID
, 3 AS TEST
UNION
SELECT 'B35' AS ID
, 1 AS TEST
UNION
SELECT 'B35' AS ID
, 2 AS TEST
)
SELECT *
FROM FRED F
这对我有用:
--Construct sample data.
WITH FRED AS
(
SELECT 'A12' AS ID
, 1 AS TEST
UNION
SELECT 'A12' AS ID
, 2 AS TEST
UNION
SELECT 'A12' AS ID
, 3 AS TEST
UNION
SELECT 'A12' AS ID
, 5 AS TEST
UNION
SELECT 'A12' AS ID
, 8 AS TEST
UNION
SELECT 'B35' AS ID
, 1 AS TEST
UNION
SELECT 'B35' AS ID
, 3 AS TEST
),
--This is the sample data
test_data AS
(
SELECT *
FROM FRED F
ORDER BY ID, TEST
)
SELECT td.ID, td.TEST as RANGE1, MIN(td2.TEST) as RANGE2
FROM test_data td
cross join test_data td2
WHERE td.ID = td2.ID
AND
td.TEST < td2.TEST
GROUP BY td.ID, td.TEST
ORDER BY td.ID, td.TEST
test_data给出了你提供的样本。一旦你让我们都知道你希望如何处理这些价值案例,我就可以尝试处理重复的价值案例。上面的当前代码没有这样做。
假设这是 mysql(但大多数其他 DBMS 也会这样做),您可以将 table 与其自身连接起来,并在 ON 子句中使用限制。
最小值和分组可以帮助你。
例如:
mysql> SELECT m.id, m.test AS RANGE1 ,min(mm.test) AS RANGE2
FROM table1 AS m
INNER JOIN table1 AS mm ON m.id=mm.id AND mm.test > m.test
GROUP BY m.id,m.test;
+------+--------+--------+
| id | RANGE1 | RANGE2 |
+------+--------+--------+
| a12 | 1 | 2 |
| a12 | 2 | 3 |
| a12 | 3 | 5 |
| a12 | 5 | 8 |
| b35 | 1 | 3 |
+------+--------+--------+
5 rows in set (0.00 sec)
注意这些事情的效率。
您可能需要研究如何处理 table 中不存在第二个值的边缘情况。
我想弄清楚如何(或看看是否可能)我可以获取 'TEST' 的最小值并获取 'TEST' 的下一个最小值,然后再次加入并继续第二个最小值,等等,等等
表 1
ID TEST
A12 1
A12 2
A12 3
A12 5
A12 8
B35 1
B35 3
我想要的结果:
ID RANGE1 RANGE2
A12 1 2
A12 2 3
A12 3 5
A12 5 8
B35 1 3
table 我使用的代码:
WITH FRED AS
(
SELECT 'A12' AS ID
, 1 AS TEST
UNION
SELECT 'A12' AS ID
, 2 AS TEST
UNION
SELECT 'A12' AS ID
, 3 AS TEST
UNION
SELECT 'B35' AS ID
, 1 AS TEST
UNION
SELECT 'B35' AS ID
, 2 AS TEST
)
SELECT *
FROM FRED F
这对我有用:
--Construct sample data.
WITH FRED AS
(
SELECT 'A12' AS ID
, 1 AS TEST
UNION
SELECT 'A12' AS ID
, 2 AS TEST
UNION
SELECT 'A12' AS ID
, 3 AS TEST
UNION
SELECT 'A12' AS ID
, 5 AS TEST
UNION
SELECT 'A12' AS ID
, 8 AS TEST
UNION
SELECT 'B35' AS ID
, 1 AS TEST
UNION
SELECT 'B35' AS ID
, 3 AS TEST
),
--This is the sample data
test_data AS
(
SELECT *
FROM FRED F
ORDER BY ID, TEST
)
SELECT td.ID, td.TEST as RANGE1, MIN(td2.TEST) as RANGE2
FROM test_data td
cross join test_data td2
WHERE td.ID = td2.ID
AND
td.TEST < td2.TEST
GROUP BY td.ID, td.TEST
ORDER BY td.ID, td.TEST
test_data给出了你提供的样本。一旦你让我们都知道你希望如何处理这些价值案例,我就可以尝试处理重复的价值案例。上面的当前代码没有这样做。
假设这是 mysql(但大多数其他 DBMS 也会这样做),您可以将 table 与其自身连接起来,并在 ON 子句中使用限制。
最小值和分组可以帮助你。
例如:
mysql> SELECT m.id, m.test AS RANGE1 ,min(mm.test) AS RANGE2
FROM table1 AS m
INNER JOIN table1 AS mm ON m.id=mm.id AND mm.test > m.test
GROUP BY m.id,m.test;
+------+--------+--------+
| id | RANGE1 | RANGE2 |
+------+--------+--------+
| a12 | 1 | 2 |
| a12 | 2 | 3 |
| a12 | 3 | 5 |
| a12 | 5 | 8 |
| b35 | 1 | 3 |
+------+--------+--------+
5 rows in set (0.00 sec)
注意这些事情的效率。
您可能需要研究如何处理 table 中不存在第二个值的边缘情况。