sql - 在多行满足连接条件的情况下随机连接
问题描述
这是我的 SQLite 数据的一个非常简化的版本:
CREATE Table Questionnaires
(
questionnaire_id INTEGER NOT NULL,
seconds INTEGER NOT NULL,
measure CHAR(4) NOT NULL,
score INTEGER NOT NULL,
PRIMARY KEY (questionnaire_id)
)
INSERT INTO Questionnaires (seconds, measure, score) VALUES (5, 'PHQ9', 10), (5, 'GAD7', 8), (20, 'PHQ9', 5)
CREATE Table Events
(
event_id INTEGER NOT NULL,
seconds INTEGER NOT NULL,
PRIMARY KEY (event_id)
)
INSERT INTO Events (seconds) VALUES (5), (5), (10), (15), (20)
我想加入这两个表seconds
。我目前的尝试没有给出我想要的结果:
SELECT
Events.event_id,
Questionnaires.questionnaire_id,
Questionnaires.seconds,
Questionnaires.measure,
Questionnaires.score
FROM Questionnaires
LEFT OUTER JOIN Events
ON Events.seconds = Questionnaires.seconds
有两个问卷seconds == 5
和两个事件,seconds == 5
所以LEFT OUTER JOIN
给了我四个结果行,即
- 问卷 1 与事件 1 相结合,
- 问卷 1 与事件 2 相结合,
- 问卷 2 与事件 1 相结合,以及
- 问卷 2 与事件 2 相结合。
但我想要的是要么
- 问卷 1 与事件 1 结合,问卷 2 与事件 2 结合,或
- 问卷 1 与事件 2 结合,问卷 2 与事件 1 结合。
我不介意我得到哪一个。
我可以看到如何在过程语言中做到这一点,但我看不到如何在 SQL 中以集合论的方式做到这一点。
有任何想法吗?
(注意在我的真实数据集中重复匹配事件很少见,这就是为什么我没有发现我的愚蠢错误。)
解决方案
在加入之前,您可以在两个表上使用row_number()
窗口函数:
select
e.event_id,
q.questionnaire_id,
q.seconds,
q.measure,
q.score
from (
select *, row_number() over (partition by seconds order by questionnaire_id) rn
from Questionnaires
) q left join (
select *, row_number() over (partition by seconds order by event_id) rn
from Events
) e on e.seconds = q.seconds and e.rn = q.rn
请参阅演示。
或者没有窗口函数:
SELECT
e.event_id,
q.questionnaire_id,
q.seconds,
q.measure,
q.score
FROM Questionnaires q LEFT OUTER JOIN Events e
ON e.seconds = q.seconds
AND (select count(*) from Questionnaires where seconds = q.seconds and questionnaire_id < q.questionnaire_id) =
(select count(*) from Events where seconds = e.seconds and event_id < e.event_id);
请参阅演示。
结果:
| event_id | questionnaire_id | seconds | measure | score |
| -------- | ---------------- | ------- | ------- | ----- |
| 1 | 1 | 5 | PHQ9 | 10 |
| 2 | 2 | 5 | GAD7 | 8 |
| 5 | 3 | 20 | PHQ9 | 5 |
推荐阅读
- api - API数据展示——flutter card widget
- android - 前台服务问题 - 然后没有调用 Service.startForeground()
- python - 将多个时间戳行合并为一个
- vue.js - 组合api使用这个
- flutter - AppBar 可在不同页面重用和路由在不同页面效果
- spring-boot - Spring Boot Hikari 连接池问题
- java - Java程序文件输出上传到Squarespace网站
- python - 为什么 Docker for Tensorflow GPU 容器回退到 CPU?
- jquery - 追随者的Jquery未触发
- r - 在 R 中创建损耗权重的逆概率