我的数据如下:
简而言之,House有很多Box,每个Box都有很多东西。此外,每个房子都有很多业主。
如果我认识两位业主(比如彼得和保罗),我怎样才能列出这些人所拥有的房屋内的所有物品?
另外,我想掌握这个SQL的东西。任何人都可以推荐一本好书/资源吗? (我正在使用MySQL)。
谢谢!
答案 0 :(得分:1)
SELECT
Things_in_boxes.*
FROM
Houses
JOIN Boxes ON Houses.HouseID = Boxes.House
JOIN Things_in_boxes ON Boxes.BoxID = Things_in_boxes.Box
WHERE
Houses.Owner = 'Peter' OR Houses.Owner = 'Paul'
至于要学习的资源......我无法真正提出具体建议。我学会了如何逐步地使用(我的)SQL并从多个来源,并且不能将它们中的任何一个单独用作最重要的。 w3schools可以覆盖非常基本的东西,而且MySQL自己的文档(可在网上找到,google for it)做得很好,并且当你想知道某个主题或其他主题的细节时,它是一个合理的参考。
编辑:以上答案是错误的。我错过了众议院可以拥有多个业主的规定。新方法:我假设有一个交叉引用表,HouseOwners,House和Owner作为外键。
我的第一个想法是:
SELECT
Things_in_boxes.*
FROM
Houses
JOIN Boxes ON Houses.HouseID = Boxes.House
JOIN Things_in_boxes ON Boxes.BoxID = Things_in_boxes.Box
JOIN HouseOwners ON Houses.HouseID = HouseOwners.House
WHERE
HouseOwners.Owner = 'Peter' OR HouseOwners.Owner = 'Paul'
但是,这不太对。如果彼得和保罗都是某个房子的主人,那么那所房子里的东西就会出现两次。我认为需要子查询。
SELECT
Things_in_boxes.*
FROM
Houses
JOIN Boxes ON Houses.HouseID = Boxes.House
JOIN Things_in_boxes ON Boxes.BoxID = Things_in_boxes.Box
WHERE
Houses.HouseID IN (
SELECT DISTINCT House
FROM HouseOwners
WHERE Owner = 'Peter' OR Owner = 'Paul'
) AS MySubquery
答案 1 :(得分:1)
然后查询
select item from houses as h
left join Boxes as b on h.houseID=b.houseID
left join Things as t on b.boxID=t.boxID
left join Houses2Owners as h2o on h.houseID=h2o.houseID
left join Owners as o on h2o.ownerID=o.ownerID
在设计时你应该问自己的主要问题是每个对象是否会出现一次,即。如果有两个类似的东西在他们或类似的东西。两个带滑雪面罩的盒子。
然后,您应该创建与父对象无关的表,并创建连接两个表的表。这样你就可以避免两个包含该面具的盒子出现两次滑雪面罩。
答案 2 :(得分:0)
SELECT t.name
FROM Houses h
INNER JOIN Boxes b ON b.houseId = h.id
INNER JOIN Things t ON t.boxId = b.id
INNER JOIN Owners o ON o.houseId = h.id
WHERE o.name = 'Peter' OR o.name = 'Paul'
通过使用内部联接,您可以将这4个表与所有链接信息组合在一起。还有另一种使用内部选择查询的方法:
SELECT t.name
FROM Houses h
INNER JOIN Boxes b ON b.houseId = h.id
INNER JOIN Things t ON t.boxId = b.id
INNER JOIN Owners o ON o.houseId = h.id
WHERE h.id IN (SELECT o.housId
FROM Owners o
WHERE o.name = 'Peter' OR o.name = 'Paul')
此查询的工作方式不同(首先找到彼得和保罗的两个房屋ID,然后执行连接),但效果相同。
希望这些示例能帮助您理解SQL:)
答案 3 :(得分:0)
这不是现场测试和写的:
SELECT *
FROM
`things_in_boxes` AS a
LEFT JOIN `houses` AS b
on ( a.`house_id` = b.`house_id` )
LEFT JOIN `owners` AS c
on ( b.`house_id` = c.`house_id` )
WHERE c.`owner_id` IN( 0, 1 )
这是我将使用的一般结构,其中最后IN
语句中的“0,1”是彼得和保罗的所有者ID。如果你想通过名字来做,你可以简单地做到类似
c.`name` IN( 'Peter', 'Paul' )
就书籍而言,我无法告诉你,我通过教程和参考资料学到了。
答案 4 :(得分:0)
这是一种方法:
SELECT * FROM Things_in_boxes t
WHERE box_id IN (
SELECT b.id
FROM Boxes b
INNER JOIN Owners o
ON (o.house_id = b.house_id)
WHERE o.name LIKE 'Peter'
OR o.name LIKE 'Paul'
)
请注意,您不需要加入House表,因为Box和Owners都有房屋ID。
答案 5 :(得分:0)
在不知道完整结构的情况下,我将假设一个结构来逐步构建查询
获取属于所有者的房屋的ID
从House中选择id('peter','paul')
获取这些房屋的方框
从homeid所在的方框中选择boxid(从House中选择id,其中所有者为('peter','paul'))
获取这些方框中的内容
从boxid所在的东西中选择*(从homeid所在的方框中选择boxid(从House中选择id,其中所有者为''peter','paul'))
这应该可以满足您的需求,但效率非常低。
在上面的方法中,步骤3中的最终查询获取每个步骤中的ID,并在消耗它们时将它们存储在临时存储中。在大多数DBMS中,这是一个非常慢的操作。
更好的选择是加入。合并所有表格并选择所需数据。
select * from things join boxes on things.boxid =boxes.boxid join houses on boxes.houseid=house.id join owners on houses.owner=owner.ownerid where owner.name in ('peter',''paul)