“艰难地学习SQL” - 练习13:嵌套的select语句出现问题

时间:2015-09-18 13:58:12

标签: sql sqlite select

我正在经历“艰难学习SQL”,目前我正在练习13。

我被困在我们必须的部分

  

写一个查询,找到宠物及其主人的所有名字   2004年以后购买。关键是要根据人物地图绘制person_pet   purchase_on列给宠物和父母。

我的表格看起来像这样

sqlite> select * from person ; 
id          first_name  last_name   age         dead        phone_number  salary      dob       
----------  ----------  ----------  ----------  ----------  ------------  ----------  ----------
0           john        doe         20          0           9929          123123.0    2015-12-09
1           foo         bar         25          0           12            123123.0    2004-12-11
2           michal      jordan      19          0           12            123123.0    2005-12-11
3           tom         ford        30          0           12            123123.0    2002-12-11

并且

sqlite> select * from pet ; 
id          name        breed       age         dead        dob         parent_id 
----------  ----------  ----------  ----------  ----------  ----------  ----------
0           fluffy      Unicorn     5           0           2012-02-01            
1           quora       social net  10          0           2010-02-01            
2           Goldie      German She  6           0           2009-02-01            
3           boxer       golden ret  3           0           2007-02-01            
4           naman       kutta       10          1           2011-02-01            
5           hari        ohk         7           0           2015-02-01


sqlite> select * from person_pet ; 
person_id   pet_id      purchased_on
----------  ----------  ------------
2           2           2002-03-30  
2           3           2001-04-30  
2           4           2005-04-30  
2           5           2003-04-30  
3           1           2006-04-30  
3           4           2005-04-30    

我的schema看起来像这样

sqlite> .schema
CREATE TABLE person(
 id INTEGER PRIMARY KEY, 
 first_name TEXT,
 last_name TEXT, 
 age INTEGER
, dead INTEGER, phone_number INTEGER, salary FLOAT, dob DATETIME);
CREATE TABLE pet(
 id INTEGER PRIMARY KEY, 
 name TEXT, 
 breed TEXT, 
 age INTEGER, 
 dead INTEGER
, dob DATETIME, parent_id INTEGER);
CREATE TABLE person_pet(
 person_id INTEGER, 
 pet_id INTEGER
, purchased_on DATETIME);
CREATE TABLE cars(
 id INTEGER PRIMARY KEY,
 car_name TEXT
);

我尝试了什么

我可以通过查询获得{2004年之后带来的person_idpet_id

sqlite> select person_id, pet_id, purchased_on from person_pet 
   ...> where purchased_on > "2004-01-01" ;
person_id   pet_id      purchased_on
----------  ----------  ------------
2           4           2005-04-30  
3           1           2006-04-30  
3           4           2005-04-30

我该如何处理现在的名字?

这是我第一次使用SQL,所以任何帮助都会非常感激。被困在这一段时间了。

修改

我知道这可以使用joins来完成,但是直到练习13都没有涵盖。如何在不使用joins的情况下执行此操作?

正如@vkp在评论中所说,in至今已被覆盖。

3 个答案:

答案 0 :(得分:3)

你也需要join其他两张表。

select pp.person_id, pp.pet_id, pp.purchased_on, pt.name, p.first_name, p.last_name 
from person_pet pp
inner join person p on p.id = pp.person_id
inner join pet pt on pt.id = pp.pet_id
where purchased_on > "2004-01-01"

答案 1 :(得分:1)

要使用相关名称替换ID,您可以使用correlated subqueries

select (select first_name
        from person
        where id = person_pet.person_id),
       (select name
        from pet
        where id = person_pet.pet_id),
       purchased_on
from person_pet
where purchased_on >= '2005';

(当您需要从同一个表中获取多个列时(例如,名字和姓氏),这比连接效率低。)

答案 2 :(得分:0)

虽然这是落后的,但至少可以说它应该有效:

select person_id, (select max(first_name)+' '+max(last_name) from person where id = person_id) as person_name, pet_id, (select max(name) from pet where id = pet_id) as pet_name, purchased_on from person_pet 
   ...> where purchased_on > "2004-01-01" ;

PS - 使用IN无济于事,因为你必须从两个额外的表中获取数据。如果它只是一个额外的表,它会很好地工作。

PPS - this基本上是一个联接。也尝试使用它。