我一直试图解决它但失败了。我有我的问题的快照,它已被削减。我想要的是以下内容:
action_id event_id link text duration
339054 10221877 317547 text1 30
339057 10221877 317548 text2 45
339061 10221877 317549 text3 30
339065 10221877 317551 text4 40
339074 10221877 317550 text5 60
339075 10221877 317552 text6 80
只用两张桌子就可以了吗?如果没有,可能会有什么帮助?
CREATE TABLE time1
(
prim int (5),
booking int (5) PRIMARY KEY,
duration int (5));
insert into time1 values
( 10221877, 296480,30),
( 10221877, 296484,45),
( 10221877, 296487,30),
( 10221877, 296492,40),
( 10221877, 296494,60),
( 10221877, 296510,80),
( 10221877, 296511,11);
CREATE TABLE action1
(
action_id int (5) PRIMARY KEY,
event_id int (5),
link int (5),
text_text VARCHAR(255)
);
insert into action1 values
(339054,10221877,317547,"text1"),
(339057,10221877,317548,"text2"),
(339061,10221877,317549,"text3"),
(339065,10221877,317551,"text4"),
(339074,10221877,317550,"text5"),
(339075,10221877,317552,"text6");
正如我所看到的,您希望将action1表的第一行连接到time1表的第一行,将action1表的第二行连接到time1的第二行,依此类推。因此,您可以使用variables来计算行的序数和连接表。例如:
SELECT a.action_id, a.event_id, a.link, a.text_text, t.duration
FROM (SELECT action_id,
event_id,
link,
text_text,
IF(@event_id = event_id, @rownumber := @rownumber + 1, @rownumber := 0) as rownumber,
@event_id := event_id
FROM action1,
(SELECT @event_id := 0, @rownumber := 0) AS rn) as a
LEFT JOIN
(SELECT duration,
prim,
IF(@prim = prim, @rownumber := @rownumber + 1, @rownumber := 0) as rownumber,
@prim := prim
FROM time1,
(SELECT @prim := 0, @rownumber := 0) AS rn) as t ON a.event_id = t.prim AND a.rownumber = t.rownumber
结果是
--------------------------------------------------------
| action_id | event_id | link | text_text | duration |
--------------------------------------------------------
| 339054 | 10221877 | 317547 | text1 | 30 |
| 339057 | 10221877 | 317548 | text2 | 45 |
| 339061 | 10221877 | 317549 | text3 | 30 |
| 339065 | 10221877 | 317551 | text4 | 40 |
| 339074 | 10221877 | 317550 | text5 | 60 |
| 339075 | 10221877 | 317552 | text6 | 80 |
--------------------------------------------------------
在DBFiddle的演示
你想要的看起来有点像JOIN
,看看this answer right here,因为它有很多关于连接的信息,我会尝试做以下查询
SELECT * FROM `time1` INNER JOIN `action1` ON `time1`.`prim` = `action1`.`event_id`
如果我理解你正确输入的数据。
您可以使用windows functions
尝试类似下面的内容来获得结果。在这里,我加入2个表并为每行分配row_number()
,然后使用DENSE_RANK()
分配组号,然后通过匹配rownumber和groupnumber获得结果。希望这可以帮助。
select action_id,event_id,link,text_text,duration from (
select action1.*,duration,(row_number() over (partition by action1.action_id)) as rowno,
(dense_rank() over (order by action1.action_id)) as groupno from action1
join time1
on action1.event_id = time1.prim
) as mytable
where mytable.rowno = mytable.groupno
你可以在这里查看结果:DEMO HERE
我在MySQL 8.0上使用窗口函数使用它:
SELECT a.action_id, a.event_id, a.link, a.text_text, t.duration
FROM (SELECT *, ROW_NUMBER() OVER () AS rownum FROM time1 ORDER BY booking) AS t
JOIN (SELECT *, ROW_NUMBER() OVER () AS rownum FROM action1 ORDER BY action_id) AS a
USING (rownum)
输出:
+-----------+----------+--------+-----------+----------+
| action_id | event_id | link | text_text | duration |
+-----------+----------+--------+-----------+----------+
| 339054 | 10221877 | 317547 | text1 | 30 |
| 339057 | 10221877 | 317548 | text2 | 45 |
| 339061 | 10221877 | 317549 | text3 | 30 |
| 339065 | 10221877 | 317551 | text4 | 40 |
| 339074 | 10221877 | 317550 | text5 | 60 |
| 339075 | 10221877 | 317552 | text6 | 80 |
+-----------+----------+--------+-----------+----------+
我必须评论根据行号加入行是非常规的。对行不应该有任何隐式顺序,您应该只通过值而不是行位置来连接它们。
在你的例子中,booking
数似乎在增加,但我不知道这是你数据中的可靠假设,还是你的例子中的巧合。而且我不知道我是否正确地假设您希望按位置连接的行。这与你的例子相符,但同样可能只是巧合。
当有多个event_id
值时,我也无法从你的例子中看出你想如何进行连接。你希望行编号重新开始,或者只是逐行匹配row_number()
?如果两个表中每个event_id
有不同的行数,该怎么办?你需要使用LEFT OUTER JOIN
吗?还是FULL OUTER JOIN
?