Sql 有没有办法限制左外连接?
我有一个具有以下格式的日志表(和示例数据): 我要进行SQL查询,该查询将检索以下格式的结果:Sql 有没有办法限制左外连接?,sql,postgresql,Sql,Postgresql,我有一个具有以下格式的日志表(和示例数据): 我要进行SQL查询,该查询将检索以下格式的结果: date1 | time1 | date2 | time2 2010/01/02 | 10:00 | 2010/01/02 | 13:00 2010/01/02 | 13:00 | 2010/01/04 | 02:34 2010/01/04 | 02:34 | <null> | <null> 然而,这将导致以下情况: date1 | ti
date1 | time1 | date2 | time2
2010/01/02 | 10:00 | 2010/01/02 | 13:00
2010/01/02 | 13:00 | 2010/01/04 | 02:34
2010/01/04 | 02:34 | <null> | <null>
然而,这将导致以下情况:
date1 | time1 | date2 | time2
2010/01/02 | 10:00 | 2010/01/02 | 13:00
2010/01/02 | 10:00 | 2010/01/04 | 02:34
2010/01/02 | 13:00 | 2010/01/04 | 02:34
2010/01/04 | 02:34 | <null> | <null>
date1 | time1 | date2 | time2
2010/01/02 | 10:00 | 2010/01/02 | 13:00
2010/01/02 | 10:00 | 2010/01/04 | 02:34
2010/01/02 | 13:00 | 2010/01/04 | 02:34
2010/01/04 | 02:34 | |
顺便说一下,使用的数据库是PostgreSql
谢谢。在
PostgreSQL 8.4
中:
SELECT date AS date1, time AS time1,
LEAD(date) OVER (ORDER BY date, time, id) AS date2,
LEAD(time) OVER (ORDER BY date, time, id) AS time2
FROM log_table
ORDER BY
date, time, id
,或仅此而已:
SELECT date1, time1, (lnext).*
FROM (
SELECT date AS date1, time AS time1,
LEAD(lt) OVER (ORDER BY date, time, id) AS lnext
FROM log_table lt
) q
ORDER BY
date, time, id
在PostgreSQL 8.3及以下版本中:
SELECT date AS date1, time AS time1,
(li).date AS date2, (li).time AS time2
FROM (
SELECT lo.*,
(
SELECT li
FROM log_table li
WHERE (li.date, li.time, li.id) > (lo.date, lo.time, lo.id)
ORDER BY
date, time, id
LIMIT 1
) AS li
FROM log_table lo
) q
我在条款的
后面发现了一个缺失的,我想您希望'I'中的一行与'j'中的下一行配对吗?从你的描述中不太清楚。@ijw是的,'i'和'j'基本上是相同的表。如果行是根据日期和时间按顺序排序的,我希望一行与后面的行配对it@Quassnoi这是我第一次听说lead over,如果我在“i”和“j”中除了日期和时间之外还有其他专栏,它也会起作用吗?@absolute0:是的,会的。在PostgreSQL中,您可以在一个字段中选择整个记录,并在上层查询或客户端将其分解。不幸的是,我们使用的是PostgreSQL 8.1,我将尝试您的其他建议PostgreSQL 8.3和以下建议不起作用,但我一时兴起,更改了原始sql的这部分:“和(j.date>i.date或(j.date==i.date和j.time>i.time)),转换为您使用的语法:“和(j.date,j.time)>(i.date,i.time)”,由于某些原因,它可以按照我的要求工作……我也是第一次遇到这种语法。谢谢!
SELECT date1, time1, (lnext).*
FROM (
SELECT date AS date1, time AS time1,
LEAD(lt) OVER (ORDER BY date, time, id) AS lnext
FROM log_table lt
) q
ORDER BY
date, time, id
SELECT date AS date1, time AS time1,
(li).date AS date2, (li).time AS time2
FROM (
SELECT lo.*,
(
SELECT li
FROM log_table li
WHERE (li.date, li.time, li.id) > (lo.date, lo.time, lo.id)
ORDER BY
date, time, id
LIMIT 1
) AS li
FROM log_table lo
) q
SELECT
i.date as date1,
i.time as time1,
min(j.date) as date2,
min(j.time) as time2
FROM
log_table i
LEFT OUTER JOIN
log_table j
ON
i.id = j.id
AND (j.date > i.date
OR (j.date == i.date AND j.time > i.time))
GROUP BY i.date, i.time