MySQL根据表B中的行将表B合并到表A中

时间:2014-02-19 22:43:35

标签: php mysql sql

我正在尝试根据给定值合并另一个表上的一个表。但是,它并不像JOIN那么简单。 (我在网上找到了很多JOIN示例,但没有一个像这样。另外,我在数据库查询方面也不是很出色。)

对于我想要完成的一个简单示例,假设我经营一家电脑商店并向多人销售多台电脑。无论出于何种原因,这些机器定期与我联系,我想知道我的哪些客户有一台当前处于脱机状态的机器。但是,如果他们在线至少有一台机器,我不希望看到他们拥有的任何在线或离线的机器。

到目前为止,我的查询是这样的:

SELECT * 
FROM Computers
LEFT JOIN Computers_On_Customers ON Computer_ID = Computers.ID
LEFT JOIN Customers ON Computers_On_Customers.Customer_ID = Customers.ID
WHERE Computers.Currently_Online LIKE "0"

但是,如果客户有2台计算机,每台状态中的一台,它将显示1台计算机,当我希望它既不显示时也是如此。 (因为一个人目前处于离线状态,因此我不关心在线人员。)我怎么能这样做呢?

以下是我的数据库的粗略视觉近似值:

Customers:
ID     Other Stuff


Computers_On_Customers
ID     Customer_ID     Computer_ID

Computers:
ID     Currently_Online

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:1)

您可以使用NOT EXISTS过滤掉所有者在线拥有计算机的计算机:

SELECT * FROM Computers
    LEFT JOIN Computers_On_Customers ON Computer_ID = Computers.ID
    LEFT JOIN Customers ON Computers_On_Customers.Customer_ID = Customers.ID
WHERE 
    Computers.Currently_Online LIKE "0" AND 
    NOT EXISTS (
                SELECT 1 FROM Computers_On_Customers 
                    LEFT JOIN Computers ON Computer_ID = Computers.ID 
                    WHERE 
                        Currently_Online LIKE "1" AND
                        Computers_On_Customers.Customer_ID = Customers.ID
               )

答案 1 :(得分:1)

您需要执行聚合,然后获取该聚合的结果,并使用您想要的过滤器进行选择。

使用你的例子。取出位置并将其移出聚合选择。

SELECT 
    ID, offline_count
from
    (SELECT 
        Customers.ID,
            SUM(IF(Computers.Currently_Online Like '0', 0, 1)) 'offline_count'
    FROM
        Computers
    LEFT JOIN Computers_On_Customers ON Computer_ID = Computers.ID
    LEFT JOIN Customers ON Computers_On_Customers.Customer_ID = Customers.ID
    GROUP BY Customers.ID) c
where
    c.offline_count > 0

假设data_table具有指定用户是在线还是离线的信息,并且可以有多个条目。聚合用户并进行离线计数的总和,如果其>>聚合后,您知道该用户有一个离线条目。您可以使用HAVING子句实现类似的功能。

答案 2 :(得分:1)

假设您只是想要客户数据 - 当然您可以使用GROUP BY条款完成所有内容...并且因为您在之后只有最大值的记录Computers.Currently_Online = 0 MAX您应该可以使用SELECT Customers.*, MAX(Computers.Currently_Online) AS computer_online FROM Customers INNER JOIN Computers_On_Customers ON Customers.ID = Computers_On_Customers.Customer_ID INNER JOIN Computers ON Computers_On_Customers.Computer_ID = Computers.ID GROUP BY Customers.ID HAVING computer_online = 0 函数排除任何值为>的内容。 0

{{1}}

就个人而言,我不喜欢嵌套SELECT,除非我绝对必须......在这些情况下,我更愿意将它放入存储过程中。