结合两个几乎相同的MySQL查询

时间:2012-07-02 22:28:47

标签: mysql union

这个社区的新手......我不得不说我喜欢这个资源,这太棒了。 :)

(在我走得更远之前,我想指出我已经已经实现使用多个查询然后结合使用PHP数组获得的这个问题的不良但功能性的解决方案,但是我我对MySQL的弱点以及我所做的事情并不优雅或高效,我非常感谢你能给我的任何帮助来帮助我改进它。我的项目使用了几十个SQL查询和我我想学会正确地写它们。)

我实际上是在尝试合并两个几乎相同的MySQL记录集,使用UNION语句或类似的东西。我一直在寻找寻找解决方案的年代,并且此时它仍然超出我的范围。所以,这是我的第一个问题:

我的数据结构相对简单,但我怀疑我想要使用它的方式可能有点不太常见。我有一系列用户定期将数据从他们的移动设备传输到PHP服务器,PHP服务器处理它们并将其内容存储在MySQL数据库中。这可能是一个非常不正统的地方 - 用户可以在一个封闭的链条中有效地链接。在任何时候,每个用户都有另一个用户作为他们的链接,或者,我更喜欢“目标”,而他们自己则作为其他人的目标。 这个模型可以被认为是线性的:A目标B,B目标C,C目标D,D目标A。

数据存储在两个表中:

  1. 用户:包含有关用户的数据(例如UserID,姓名,年龄等等... TargetID)
  2. :包含有关所有用户更新的数据(例如UserID,Timestamp等等)
  3. 收到用户的请求后,我想:

    1. 首先,从Packages表中提取最新更新,以及与用户目标相关的用户表中的个人信息。
    2. 其次,从Packages表中提取最新的更新,以及来自Users表的个人信息中的个人信息。
    3. 这可能有点令人困惑,所以要澄清: 使用上述模型,如果我收到来自B的请求,我想要从A中获取最新的包,并在单个记录集中返回最新的C包,以及相关的传记信息。 我实际上对B不感兴趣!

      此时我设法达到的最佳目标是三个查询:

      1. 最初,检查Users表以获取用户的正确TargetID。

        SELECT TargetID FROM Users WHERE Users.UserID = [VALUE SUBMITTED IN USER REQUEST];
        
      2. 查询两个表以生成结果1.

        SELECT Users.UserID, Users.Name, Users.TargetID, Packages.Timestamp, Packages.Latitude, Packages.Longitude, Packages.Message FROM Users, Packages WHERE Packages.UserID = Users.UserID AND Users.UserID = [VALUE OBTAINED FROM QUERY 1] ORDER BY Packages.Timestamp DESC LIMIT 0,1;
        
      3. 查询两个表以生成结果2.

        SELECT Users.UserID, Users.Name, Users.TargetID, Packages.Timestamp, Packages.Latitude, Packages.Longitude, Packages.Message FROM Users, Packages WHERE Packages.UserID = Users.UserID AND Users.TargetID = [VALUE SUBMITTED IN USER REQUEST] ORDER BY Packages.Timestamp DESC LIMIT 0,1;
        
      4. 然后我合并了结果1& 2在PHP数组中,并将此数组的内容发送回提交请求的用户。在任何涉及许多此类请求的情况下,我很难相信这种方法是有效的,更不用说理想了。尽管Queries 2& 3实际上是相同的,我确信WHERE子句中的一个简单OR条件应该能够将它们组合起来,如果没有为我感兴趣的用户返回所有包,或者只返回一个,我就无法成功地这样做记录,丢弃第二个(我明确地应用了时间限制)。例如,MySQL抱怨我有时不正确地使用UNION和ORDER BY语句。每次我尝试修改它时,我的语法都会出错。

        我对目前的解决方案非常不满意,因为此时查看我的项目是我的服务器必须执行的单个MySQL任务,而不是其他所有任务。我确实意识到这个问题相当冗长,但我认为彻底解释事情总是更好,所以第一次可以理解。提前感谢您给我的任何指导或指导。欢呼声。

1 个答案:

答案 0 :(得分:2)

如果我理解正确,可以这样:

select 
Users.UserID, 
TargetedPackages.UserID as TargetedID,
TargetedPackages.TimeStamp as TargetedTimestamp,
TargeterPackages.UserID as TargeterID,
TargeterPackages.Timestamp as TargetedTimestamp
from 
Users

INNER JOIN Users as Targeted
on Targeted.TargetId = Users.TargetID

INNER JOIN Users as Targeter
on Targeter.TargetId = Users.UserID

LEFT JOIN Packages as TargetedPackages
on Users.TargetID = TargetedPackages.UserID AND TargetedPackages.Timestamp = (SELECT Max(Timestamp) FROM Packages where Packages.UserID = Users.TargetID)

LEFT JOIN Packages as TargeterPackages
on Targeter.UserID = TargeterPackages.UserID AND TargeterPackages.Timestamp = (SELECT Max(Timestamp) FROM Packages where Packages.UserID = Targeter.UserID)

where Users.UserID = 2