mysql - Google Big Query 中是否有任何方法可以在不重复使用* 右边的任何行的情况下一对一地进行左外连接?

标签 mysql sql join google-bigquery

我们在一个表中有一组患者,我们希望将他们中的每个患者与另一表中的患者完全匹配 - 但我们需要成对的患者,因此我们不能将一个患者与多个其他患者匹配。

Left Outer Joins 添加匹配项的每个匹配项 - 将患者匹配到每个其他可能的匹配项 - 因此我们需要一些其他方法。

我们在 SO 上看到很多关于匹配第一行的答案 - 但这使我们只能将一个患者与多个其他患者匹配 - 而不是我们需要的一对。

在 Google Big Query 的表之间是否有任何可能的方法来创建配对匹配而不重复? (即使它需要多个步骤。)


附录:这里是示例表。 如果能看到使用它的 SQL 示例会很棒。

这是需要的。

Example Source Tables:

Table A
PatientID     Race     Gender    
   1            A        F
   2            B        M
   3            A        F

Table B
PatientID
   4            A        F
   5            A        F
   6            B        M


Results Table Desired:

Table C
A.PatientID     B.PatientID_Match
    1               4
    2               6
    3               5

澄清:表 A 中的患者必须匹配表 B 中的患者。(他们不能匹配自己表中的患者。)

最佳答案

select      min (case tab when 'A' then patientID end)  as A_patientID  
           ,min (case tab when 'B' then patientID end)  as B_patientID

from       (select  tab
                   ,patientID
                   ,rank()       over (order by     race,gender)                        r
                   ,row_number() over (partition by tab,race,gender order by patientID) rn

            from    (           select 'A' as tab,A.* from A 
                    union all   select 'B' as tab,B.* from B
                    ) t
            ) t

group by    t.r
           ,t.rn

-- having       count(*) = 2
;

+-------------+-------------+
| a_patientid | b_patientid |
+-------------+-------------+
| 3           | 5           |
+-------------+-------------+
| 2           | 6           |
+-------------+-------------+
| 1           | 4           |
+-------------+-------------+

主要思想-

两个表中的行按其属性(种族、性别)分组。
这是使用 RANK 函数完成的。

在每组属性(种族、性别)中,行被排序,每个表,由他们的 patientid 。

+-----+-----------+------+--------+    +---+----+
| tab | patientid | race | gender |    | r | rn |
+-----+-----------+------+--------+    +---+----+

+-----+-----------+------+--------+    +---+----+
| A   | 1         | A    | F      |    | 1 | 1  |
+-----+-----------+------+--------+    +---+----+
| B   | 4         | A    | F      |    | 1 | 1  |
+-----+-----------+------+--------+    +---+----+

+-----+-----------+------+--------+    +---+----+
| A   | 3         | A    | F      |    | 1 | 2  |
+-----+-----------+------+--------+    +---+----+
| B   | 5         | A    | F      |    | 1 | 2  |
+-----+-----------+------+--------+    +---+----+

+-----+-----------+------+--------+    +---+----+
| A   | 2         | B    | M      |    | 5 | 1  |
+-----+-----------+------+--------+    +---+----+
| B   | 6         | B    | M      |    | 5 | 1  |
+-----+-----------+------+--------+    +---+----+

在最后阶段,行根据它们的 RANK (r) 和 ROW_NUMBER (rn) 值被分成组 (GROUP BY),这意味着每个组都有来自每个表的一行(或者只有一行,如果有的话)没有来自另一个表的匹配行)。

关于mysql - Google Big Query 中是否有任何方法可以在不重复使用* 右边的任何行的情况下一对一地进行左外连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40836309/

相关文章:

objective-c - 将对象的 NSArray 连接到字符串中,但需要能够指定属性

mysql - 按位置对 mysql 查询结果排序

mysql - 优化带有文件名和日期比较的 Mysql select 查询

java - 如何更新数据集中的现有记录

SQL 用自己的文本替换 NULL 值

postgresql - Postgres - 加入更新给出了错误的结果

php - fatal error : Uncaught Error ( php mysql )

mysql - 采购 MySQL 代码时出现错误 1215 和 1146

sql - 如何在不过多往返数据库的情况下使用 SQL AUTOINCREMENT 主键?

mysql - SQL : Compare if column values in two tables are equal