MySQL:获取该行的直接兄弟姐妹
MySQL: Get direct siblings of the row
我对 select 主行的直接兄弟姐妹有疑问。例如,这是我需要过滤的数据:
+------+------------+------------+
| id | from | to |
+------+------------+------------+
| 2265 | 2016-03-30 | 2016-04-09 |
| 1420 | 2016-03-30 | 2016-04-11 |
| 2261 | 2016-03-30 | 2016-04-12 |
| 2262 | 2016-04-01 | 2016-04-12 |
| 1296 | 2016-04-01 | 2016-04-24 |
| 1053 | 2016-04-01 | 2016-05-01 |
| 2302 | 2016-04-30 | 2016-05-24 |
| 2025 | 2016-05-14 | 2016-06-06 |
| 2392 | 2016-05-20 | 2016-05-28 |
| 2033 | 2016-05-21 | 2016-06-08 |
| 2389 | 2016-05-25 | 2016-06-09 |
+------+------------+------------+
我只需要 select 行,它是 min/max 日期前的直系兄弟姐妹。例如,结果应该是:
+------+------------+------------+
| id | from | to |
+------+------------+------------+
| 1296 | 2016-04-01 | 2016-04-24 |
| 1053 | 2016-04-01 | 2016-05-01 |
| 2302 | 2016-04-30 | 2016-05-24 |
+------+------------+------------+
第 1053
行是第 "main" 行。
我知道它有 MIN
和 MAX
功能,但我不知道如何使用它。我可以在我的应用程序中执行此操作,但由于性能原因,我宁愿在 SQL 中执行此操作。
您似乎需要类似以下查询的内容:
SELECT m.*
FROM mytable AS m
JOIN (
SELECT id,
(SELECT id
FROM mytable AS t2
WHERE t1.id <> t2.id AND t1.`to` >= t2.`to`
ORDER BY `to` DESC, `from` DESC LIMIT 1) AS prev_id,
(SELECT id
FROM mytable AS t3
WHERE t1.id <> t3.id AND t1.`to` <= t3.`to`
ORDER BY `to`, `from` LIMIT 1) AS next_id
FROM mytable AS t1
WHERE id = 1053
) AS t ON m.id IN (t.id, t.prev_id, t.next_id)
上面的查询使用了两个相关的子查询来获取关于具有指定[=的记录的previous和next记录11=] 值。
这是一个利用 user variable
.
的方法
select t1.id, t1.from, t1.to
from
(select *, @rn1 := @rn1 + 1 as row_num from t
cross join (select @rn1 := 0) p1) t1
cross join (select @target :=
(select t2.row_num
from (select *, @rn2 := @rn2 + 1 as row_num from t
cross join (select @rn2 := 0) p2) t2
where t2.id = 1053)
) p3
where t1.row_num in (@target-1, @target, @target+1);
要在您的 table 上使用它,请将 t
替换为您自己的 table 名称。
我对 select 主行的直接兄弟姐妹有疑问。例如,这是我需要过滤的数据:
+------+------------+------------+
| id | from | to |
+------+------------+------------+
| 2265 | 2016-03-30 | 2016-04-09 |
| 1420 | 2016-03-30 | 2016-04-11 |
| 2261 | 2016-03-30 | 2016-04-12 |
| 2262 | 2016-04-01 | 2016-04-12 |
| 1296 | 2016-04-01 | 2016-04-24 |
| 1053 | 2016-04-01 | 2016-05-01 |
| 2302 | 2016-04-30 | 2016-05-24 |
| 2025 | 2016-05-14 | 2016-06-06 |
| 2392 | 2016-05-20 | 2016-05-28 |
| 2033 | 2016-05-21 | 2016-06-08 |
| 2389 | 2016-05-25 | 2016-06-09 |
+------+------------+------------+
我只需要 select 行,它是 min/max 日期前的直系兄弟姐妹。例如,结果应该是:
+------+------------+------------+
| id | from | to |
+------+------------+------------+
| 1296 | 2016-04-01 | 2016-04-24 |
| 1053 | 2016-04-01 | 2016-05-01 |
| 2302 | 2016-04-30 | 2016-05-24 |
+------+------------+------------+
第 1053
行是第 "main" 行。
我知道它有 MIN
和 MAX
功能,但我不知道如何使用它。我可以在我的应用程序中执行此操作,但由于性能原因,我宁愿在 SQL 中执行此操作。
您似乎需要类似以下查询的内容:
SELECT m.*
FROM mytable AS m
JOIN (
SELECT id,
(SELECT id
FROM mytable AS t2
WHERE t1.id <> t2.id AND t1.`to` >= t2.`to`
ORDER BY `to` DESC, `from` DESC LIMIT 1) AS prev_id,
(SELECT id
FROM mytable AS t3
WHERE t1.id <> t3.id AND t1.`to` <= t3.`to`
ORDER BY `to`, `from` LIMIT 1) AS next_id
FROM mytable AS t1
WHERE id = 1053
) AS t ON m.id IN (t.id, t.prev_id, t.next_id)
上面的查询使用了两个相关的子查询来获取关于具有指定[=的记录的previous和next记录11=] 值。
这是一个利用 user variable
.
select t1.id, t1.from, t1.to
from
(select *, @rn1 := @rn1 + 1 as row_num from t
cross join (select @rn1 := 0) p1) t1
cross join (select @target :=
(select t2.row_num
from (select *, @rn2 := @rn2 + 1 as row_num from t
cross join (select @rn2 := 0) p2) t2
where t2.id = 1053)
) p3
where t1.row_num in (@target-1, @target, @target+1);
要在您的 table 上使用它,请将 t
替换为您自己的 table 名称。