2014-02-19 50 views
0

我试图根据给定的值合并另一个表上的一个表。但是,它并不像JOIN那么简单。 (我在网上发现了很多JOIN示例,但没有一个是这样的,而且,我在DB查询方面的表现并不令人难以置信。)MySQL基于表B行中的值将表B合并到表A中

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

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

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台电脑,每一个状态,它会显示一台电脑,当我想让它显示两者都不是。 (因为一个人目前处于离线状态,所以我不在乎在线的人。)我怎么能解决这个问题?

这里是我的数据库的粗略视觉近似:

Customers: 
ID  Other Stuff 


Computers_On_Customers 
ID  Customer_ID  Computer_ID 

Computers: 
ID  Currently_Online 

任何帮助将不胜感激。

+0

仍在挣扎?考虑提供适当的DDL(和/或一个sqlfiddle)与期望的结果集合 – Strawberry

+0

感谢您的帮助家伙!所有3个查询都很有趣,并且让我看起来很棒。我不确定哪一个答案是“一个真正的答案”,但我会在有一个答案时更新。再次感谢! – Dwebtron

回答

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有信息来指定用户是在线还是离线,并且可以有多个条目。合计用户并完成离线计数的总和,如果聚合后> 0,则知道该用户有离线输入。您可以使用HAVING子句实现类似。

+0

所有3个答案都很棒,但是这个答案真的让我走上了正确的道路,我需要成为什么样的人。再次感谢你们! – Dwebtron

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

假设你只是想客户数据 - 当然你可以滚了整个事情了一个GROUP BY条款......既然你只记录,你应该能够使用的Computers.Currently_Online = 0最大值之后一个MAX功能,以排除任何地方该值> 0

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 

我个人不喜欢嵌套的SELECT,除非我绝对要...在这些情况下,我宁愿把它变成一个存储过程。

相关问题