我不确定问题的标题!,但是我有这个问题
table1
id | from | to
1 A B
2 C A
3 B A
table2
id | table1_id
1 1
2 1
3 1
4 3
5 3
6 2
7 2
8 2
我需要从table1获取数据,并将具有id(2,3)的行视为一行,并与table2联接
获取它们之间的最后一个ID 5
结果
id | from | to | table2_id
3 B | A | 5
2 C | A | 8
答案 0 :(得分:0)
您没有提到数据库,我已经在SQL Server中编写了SQL
WITH TAB_FLAT AS
(
SELECT TAB_1.table1_id , COALESCE ( TAB_2.table2_id , TAB_1.table2_id ) max_id , TAB_1.table2_id FROM
( select table1_id , max(id) table2_id from table2 group by table1_id ) TAB_1
LEFT JOIN
( select table1_id , max(id) table2_id from table2 group by table1_id ) TAB_2
ON TAB_1.table2_id = TAB_2.table1_id
)
select TAB_FLAT.table1_id AS ID, COALESCE(C.frm ,COALESCE(B.frm,A.frm) ) AS 'FROM' ,
COALESCE(C.to2 ,COALESCE(B.to2,A.to2) ) AS 'TO' ,
TAB_FLAT.max_id AS table2_id
FROM TAB_FLAT
LEFT JOIN table1 A ON A.id = TAB_FLAT.table1_id
LEFT JOIN table1 B ON B.id = TAB_FLAT.table2_id
LEFT JOIN table1 C ON C.id = TAB_FLAT.max_id
WHERE TAB_FLAT.table1_id IN (1,2)
演示-> https://rextester.com/DCHUN74655
说明:
SELECT TAB_1.table1_id , COALESCE ( TAB_2.table2_id , TAB_1.table2_id ) max_id , TAB_1.table2_id FROM
( select table1_id , max(id) table2_id from table2 group by table1_id ) TAB_1
LEFT JOIN
( select table1_id , max(id) table2_id from table2 group by table1_id ) TAB_2
ON TAB_1.table2_id = TAB_2.table1_id
我们正在执行自左联接,以获取每个表1 ID的最大表2 ID AND相应的中间级别。
select TAB_FLAT.table1_id AS ID, COALESCE(C.frm ,COALESCE(B.frm,A.frm) ) AS 'FROM' ,
COALESCE(C.to2 ,COALESCE(B.to2,A.to2) ) AS 'TO' ,
TAB_FLAT.max_id AS table2_id
FROM TAB_FLAT
LEFT JOIN table1 A ON A.id = TAB_FLAT.table1_id
LEFT JOIN table1 B ON B.id = TAB_FLAT.table2_id
LEFT JOIN table1 C ON C.id = TAB_FLAT.max_id
我们正在基于表1 id,中间id和最大id加入表1
WHERE TAB_FLAT.table1_id IN (1,2)
过滤出ID为1或2的记录
答案 1 :(得分:-1)
首先,编写查询以获取表2中每一行的最大ID。
select t1.*, max(t2.id) as table2_id
from table2 t2
join table1 t1 on t2.table1_id = t1.id
group by t1.id
然后将其用作两个查询的CTE。一种用于获取除 1和3之外的所有行。另一种用于获取1或3,以较大的table2_id为准。 union
一起。
with max_table2 as (
select t1.*, max(t2.id) as table2_id
from table2 t2
join table1 t1 on t2.table1_id = t1.id
group by t1.id
)
select *
from max_table2
where id not in (1,3)
union
(
select *
from max_table2
where id in (1,3)
order by table2_id desc
limit 1
)
如果合并的1/3行必须的ID为1,尽管3的table2_id较大,则可以通过在选择查询中对ID进行硬编码来实现。
with max_table2 as (
select t1.*, max(t2.id) as table2_id
from table2 t2
join table1 t1 on t2.table1_id = t1.id
group by t1.id
)
select *
from max_table2
where id not in (1,3)
union
(
select 1 as id, "from", "to", table2_id
from max_table2
where id in (1,3)
order by table2_id desc
limit 1
)
我怀疑不是硬编码第1行和第3行,您实际上是将它们视为等效的,因为它们具有相同的路径,只是反向了。我们可以使该查询更通用。
首先,对from / to进行规范化,以使它们的顺序相同。在进行此操作时,还要获取其最大table2 id。
select
t1.id,
case when "from" < "to" then "from" else "to" end as "from",
case when "from" < "to" then "to" else "from" end as "to",
max(t2.id) as max_table2_id
from table2 t2
join table1 t1 on t2.table1_id = t1.id
group by t1.id
id from to max_table2_id
2 A C 8
3 A B 5
1 A B 3
然后使用相同的从/到路径对路径进行排名。
with normalized_max_table2 as (
select
t1.id,
case when "from" < "to" then "from" else "to" end as "from",
case when "from" < "to" then "to" else "from" end as "to",
max(t2.id) as table2_id
from table2 t2
join table1 t1 on t2.table1_id = t1.id
group by t1.id
)
select *,
rank() over (partition by "from", "to" order by table2_id desc) as "rank"
from normalized_max_table2
id from to table2_id rank
3 A B 5 1
1 A B 3 2
2 A C 8 1
最后,仅选择第一名。
with normalized_max_table2 as (
select
t1.id,
case when "from" < "to" then "from" else "to" end as "from",
case when "from" < "to" then "to" else "from" end as "to",
max(t2.id) as table2_id
from table2 t2
join table1 t1 on t2.table1_id = t1.id
group by t1.id
),
ranked_max_table2 as (
select *,
rank() over (partition by "from", "to" order by table2_id desc) as "rank"
from normalized_max_table2
)
select id, "from", "to", table2_id
from ranked_max_table2
where "rank" = 1
id from to table2_id
3 A B 5
2 A C 8
这是一种长期的做法。可能会有更紧凑的方法。