我正在使用一个数据库,其结构类似于下图(除了更多列)。基本上,每个人都有一个唯一的person_id和alt_id。但是,将表A连接到表C的唯一事情是表B,而表B对于每个人/ alt_id都有一对多行。
我需要获取包含person_id,alt标识及其相关形状的行。
我可以这样做:
SELECT DISTINCT a.person_id, a.color, b.alt_id, c.shape
FROM a
JOIN b ON a.person_id = b.person_id
JOIN c ON b.alt_id = c.alt_id
然而,这似乎效率低下,因为在最终使用DISTINCT缩小结果之前,它将采用具有相同alt_id的B和C行的笛卡尔积。什么是进行此查询的最佳/最有效的方式?
Table A
+-----------+-------+
| person_id | color |
+-----------+-------+
| 10 | red |
| 11 | blue |
| 12 | green |
+-----------+-------+
Table B
+-----------+--------+
| person_id | alt_id |
+-----------+--------+
| 10 | 225 |
| 10 | 225 |
| 11 | 226 |
| 11 | 226 |
| 11 | 226 |
| 12 | 227 |
+-----------+--------+
Table C
+--------+----------+
| alt_id | shape |
+--------+----------+
| 225 | square |
| 226 | circle |
| 226 | rhombus |
| 226 | ellipse |
| 227 | triangle |
+--------+----------+
答案 0 :(得分:1)
加入(select distinct * from b) b
,而不仅仅是基本表b
。
SELECT
a.person_id, a.color, b.alt_id, c.shape
FROM
a
INNER JOIN (select distinct * from b) b
ON a.person_id = b.person_id
INNER JOIN c
ON b.alt_id = c.alt_id
答案 1 :(得分:1)
在进行连接之前,您可以从b
获取不同的值列表。
SELECT DISTINCT a.person_id, a.color, b.alt_id, c.shape
FROM a
JOIN (Select Distinct person_id, alt_id from b) b ON a.person_id = b.person_id
JOIN c ON b.alt_id = c.alt_id
请注意,由于索引和统计信息,获取DISTINCT
列表并不总是一个好主意。查看实际执行计划以评估其有多好,特别是如果您有大量数据。
答案 2 :(得分:1)
您可以使用聚合以及公用表表达式(或子查询,但CTE可能更整洁):
WITH ab AS (
SELECT a.person_id, a.color, MAX(b.alt_id) AS alt_id
FROM a INNER JOIN b
ON a.person_id = b.person_id
GROUP BY a.person_id, a.color
)
SELECT ab.person_id, ab.color, ab.alt_id, c.shape
FROM ab INNER JOIN c ON ab.alt_id = c.alt_id;