简体   繁体   English

从一个表中选择所有条目,在另一个表中有两个特定条目

[英]Select all entries from one table which has two specific entries in another table

So, I have 2 tables defined like this: 因此,我有2个这样定义的表:

CREATE TABLE tblPersons (
    id   INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT
);

CREATE TABLE tblHobbies (
    person_id INTEGER REFERENCES tblPersons (id),
    hobby     TEXT
);

And for example I have 3 person added to tblPersons : 例如,我在tblPersons中添加了3个人:

1 | John
2 | Bob
3 | Eve

And next hobbies in tblHobbies : 还有tblHobbies中的下一个爱好:

1 | skiing
1 | serfing
1 | hiking
1 | gunsmithing
1 | driving
2 | table tennis
2 | driving
2 | hiking
3 | reading
3 | scuba diving

And what I need, is query which will return me a list of person who have several specific hobbies. 我需要的是查询,该查询将向我返回具有一些特定爱好的人的列表。

The only thing I could've come up with, is this: 我唯一能想到的是:

SELECT id, name FROM tblPersons
    INNER JOIN tblHobbies as hobby1 ON hobby1.hobby = 'driving'
    INNER JOIN tblHobbies as hobby2 ON hobby2.hobby = 'hiking'
    WHERE tblPersons.id = hobby1.person_id and tblPersons.id = hobby2.person_id;

But it is rather slow. 但这很慢。 Isn't there any better solution? 有没有更好的解决方案?

First, you don't have a Primary Key on tblHobbies this is one cause of slow query (and other problems). 首先,您在tblHobbies上没有主键,这是查询缓慢(以及其他问题)的原因之一。 Also you should consider creating a index on tblHobbies.hobby . 另外,您应该考虑在tblHobbies.hobby上创建索引。

Second, I'd to advice you to create a third table to evidence N:N cardinality that exists in your model and avoid redundant hobbies. 其次,我建议您创建第三个表以证明模型中存在N:N基数,并避免多余的爱好。 Something like: 就像是:

--Person
CREATE TABLE tblPersons (
    id   INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT
);

--Hobby
CREATE TABLE tblHobbies (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    hobby TEXT
);

--Associative table between Person and Hobby
CREATE TABLE tblPersonsHobbies (
    person_id INTEGER REFERENCES tblPersons (id),
    hobby_id INTEGER REFERENCES tblHobbies (id),
    PRIMARY KEY (person_id, hobby_id)
);

Adds an extra table but it's worth it. 添加一个额外的表,但这是值得的。

--Query on your current model
SELECT id, name FROM tblPersons
    INNER JOIN tblHobbies as hobby1 ON  tblPersons.id = hobby1.person_id
    WHERE hobby1.hobby IN ('driving', 'hiking');

--Query on suggested model
SELECT id, name FROM tblPersons
    INNER JOIN tblPersonsHobbies as personsHobby ON  tblPersons.id = personsHobby.person_id
    INNER JOIN tblHobbies as hobby1 ON hobby1.id = personsHobby.hobby_id
        WHERE hobby1.hobby IN ('driving', 'hiking');

You can aggregate the hobbies table to get persons with both hobbies: 您可以汇总兴趣爱好表以同时获得两个兴趣爱好的人:

select person_id
from tblhobbies
group by person_id
having count(case when hobby = 'driving' then 1 end) > 0
   and count(case when hobby = 'hiking' then 1 end) > 0

Or better with a WHERE clause restricting the records to read: 最好使用WHERE子句来限制记录的读取:

select person_id
from tblhobbies
where hobby in ('driving', 'hiking')
group by person_id
having count(distinct hobby) =2

(There should be a unique constraint on person + hobby in the table, though. Then you could remove the DISTINCT . And as I said in the comments section it should even be person_id + hobby_id with a separate hobbies table. EDIT: Oops, I should have read the other answer. Michal suggested this data model three hours ago already :-) (不过,表中的person + hobby应该有一个唯一的约束。然后,您可以删除DISTINCT 。正如我在评论部分中所说的,它甚至应该是person_id + hobby_id,并带有一个单独的hobby表。编辑:糟糕,我本应该阅读其他答案的。Michal已经在三个小时前提出了这个数据模型:-)

If you want the names, select from the persons table where you find the IDs in above query: 如果需要名称,请从人员表中选择,在上面的查询中找到ID:

select id, name
from tblpersons
where id in
(
  select person_id
  from tblhobbies
  where hobby in ('driving', 'hiking')
  group by person_id
  having count(distinct hobby) =2
);

With the better data model you'd replace 使用更好的数据模型,您将取代

  from tblhobbies
  where hobby in ('driving', 'hiking')
  group by person_id
  having count(distinct hobby) =2

with

  from tblpersonhobbies
  where hobby_id in (select id from tblhobbies where hobby in ('driving', 'hiking'))
  group by person_id
  having count(*) =2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 SQL筛选器条目与另一个表中的所有条目匹配 - SQL filter entries which match all entries from another table 对于一个表中的所有条目,添加到另一个表中 - For all entries in one table, add to another table 嵌套SQL查询,其中一个表中的ID与另一个存在两个特定条目的表匹配 - Nested SQL Query where id from one table matches to another table where two specific entries exist 从一个表中选择所有条目,并从另一个“日志”表中选择“最新”条目 - Select all entries from a table and the LATEST entries from another “logging” table 从表中选择所有早于3天的条目 - Select all entries from a table which are older then 3 days 如何 select 表中的所有条目,其中子查询按第一个查询中的 id 计数另一个表中的条目 - How to select all entries in a table with a subquery counting entries in another table by id from the first query Oracle SQL:将选择从一个表插入到另一个表中,其中用户具有带有订单号的多个条目 - Oracle SQL: Insert select from one table to another where user has multiple entries with order number 从一个表中获取所有条目以及在另一个表中的这些条目的计数 - Get all entries from one table together with the count of these entries in another table 选择表中所有条目的更新表 - Update table for all entries from select statement 选择所有在特定列中具有全大写字符串的表条目? - Select all table entries which have a fully capitalized string in a specific column?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM