如何处理此SQL查询

时间:2010-06-02 08:46:21

标签: mysql

我的数据如下:

  • 房屋表
  • 一张箱子表(FK回到房屋里)
  • 一个Things_in_boxes表(带有FK回到Boxes)
  • 一张业主表(FK回到众议院)

简而言之,House有很多Box,每个Box都有很多东西。此外,每个房子都有很多业主。

如果我认识两位业主(比如彼得和保罗),我怎样才能列出这些人所拥有的房屋内的所有物品?

另外,我想掌握这个SQL的东西。任何人都可以推荐一本好书/资源吗? (我正在使用MySQL)。

谢谢!

6 个答案:

答案 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)

彼得和保罗是同性恋伴侣? 那么你应该选择多对多关系,而不是在Houses Table中拥有ownerID 即。 Houses2Owners有两列ownerID和houseID

然后查询

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)

在不知道完整结构的情况下,我将假设一个结构来逐步构建查询

  1. 获取属于所有者的房屋的ID

    从House中选择id('peter','paul')

  2. 获取这些房屋的方框

    从homeid所在的方框中选择boxid(从House中选择id,其中所有者为('peter','paul'))

  3. 获取这些方框中的内容

    从boxid所在的东西中选择*(从homeid所在的方框中选择boxid(从House中选择id,其中所有者为''peter','paul'))

  4. 这应该可以满足您的需求,但效率非常低。

    在上面的方法中,步骤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)