SQL 根据条件查询 return 个 table 个特定的匹配值
SQL Query to return a table of specific matching values based on a criteria
我在 PostgreSQL 数据库中有 3 个 table:
person (id, first_name, last_name, age)
interest (id, title, person_id REFERENCES person)
location (id, city, state text NOT NULL, country, person_id REFERENCES person)
city
可以为空,但 state
和 country
不能。
一个人可以有很多兴趣,但只有一个地方。我的挑战是 return table 有相同兴趣和地点的人。
所有 ID 都已序列化并因此自动创建。
假设我有 4 个人住在“德克萨斯州”,他们每个人都有两个兴趣,但只有第 1 个人和第 3 个人有相似的兴趣,假设是“枪支”(毕竟是德克萨斯州)。我需要 select 来自人 table 的所有人,其中此人的兴趣标题(因为 ID 是自动生成的,两个 Guns 兴趣会导致两个不同的 ID 密钥)等于另一个人的兴趣标题和城市或州也是平等的。
我在看这个问题的答案Select Rows with matching columns from SQL Server,感觉逻辑和我的问题有点相似,不同的是他有两个table,连接在一起我有三个。
return a table of people who share the same interest and location.
我将其解释为 “来自 table person
的所有行,其中存在至少共享 interest
中的一个匹配行和一个匹配行的另一行排在位置上。没有特定的顺序。"
在子查询中使用 window 函数的简单解决方案:
SELECT p.*
FROM (
SELECT person_id AS id, i.title, l.city, l.state, l.country
, count(*) OVER (PARTITION BY i.title, l.city, l.state, l.country) AS ct
FROM interest i
JOIN location l USING (person_id)
) x
JOIN person p USING (id)
WHERE x.ct > 1;
这将 NULL 值视为“相等”。 (你没有明确说明。)
根据未公开的基数,可能会有更快的查询样式。 (比如首先减少到重复的兴趣和/或位置。)
旁白 1:
拥有一个列 birthday
(或 year_of_birth
)几乎总是比 age
更好,后者会立即开始位腐烂。
旁白 2:
A person can have [...] only one location.
您至少可以在 location.person_id
上添加一个 UNIQUE
约束来强制执行。 (如果你不能让它成为 PK 或只是将位置列附加到 person
table。)
我在 PostgreSQL 数据库中有 3 个 table:
person (id, first_name, last_name, age)
interest (id, title, person_id REFERENCES person)
location (id, city, state text NOT NULL, country, person_id REFERENCES person)
city
可以为空,但 state
和 country
不能。
一个人可以有很多兴趣,但只有一个地方。我的挑战是 return table 有相同兴趣和地点的人。
所有 ID 都已序列化并因此自动创建。 假设我有 4 个人住在“德克萨斯州”,他们每个人都有两个兴趣,但只有第 1 个人和第 3 个人有相似的兴趣,假设是“枪支”(毕竟是德克萨斯州)。我需要 select 来自人 table 的所有人,其中此人的兴趣标题(因为 ID 是自动生成的,两个 Guns 兴趣会导致两个不同的 ID 密钥)等于另一个人的兴趣标题和城市或州也是平等的。
我在看这个问题的答案Select Rows with matching columns from SQL Server,感觉逻辑和我的问题有点相似,不同的是他有两个table,连接在一起我有三个。
return a table of people who share the same interest and location.
我将其解释为 “来自 table person
的所有行,其中存在至少共享 interest
中的一个匹配行和一个匹配行的另一行排在位置上。没有特定的顺序。"
在子查询中使用 window 函数的简单解决方案:
SELECT p.*
FROM (
SELECT person_id AS id, i.title, l.city, l.state, l.country
, count(*) OVER (PARTITION BY i.title, l.city, l.state, l.country) AS ct
FROM interest i
JOIN location l USING (person_id)
) x
JOIN person p USING (id)
WHERE x.ct > 1;
这将 NULL 值视为“相等”。 (你没有明确说明。)
根据未公开的基数,可能会有更快的查询样式。 (比如首先减少到重复的兴趣和/或位置。)
旁白 1:
拥有一个列 birthday
(或 year_of_birth
)几乎总是比 age
更好,后者会立即开始位腐烂。
旁白 2:
A person can have [...] only one location.
您至少可以在 location.person_id
上添加一个 UNIQUE
约束来强制执行。 (如果你不能让它成为 PK 或只是将位置列附加到 person
table。)