2

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

(在我更进一步之前,我想指出我已经使用多个查询实现了一个不受欢迎但功能强大的解决方案,然后使用 PHP 数组组合我得到的结果,但是我对 MySQL 和我所拥有的东西很弱简单地完成并不优雅或高效,我非常感谢你能给我的任何帮助来帮助我改进它。我的项目使用了几十个 SQL 查询,我想学会正确地编写它们。 )

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

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

数据存储在两个表中:

  1. 用户:包含有关用户的数据(例如,用户 ID、姓名、年龄等... TargetID)
  2. :包含有关所有用户更新的数据(例如,用户 ID、时间戳等...)

在收到用户的请求后,我想:

  1. 首先,从 Packages 表中提取最新更新,以及从 Users 表中与我们用户的目标相关的传记信息。
  2. 其次,从 Packages 表中提取最新更新,以及从 Users 表中提取与以我们的用户为目标的人有关的传记信息。

这可能有点令人困惑,所以澄清一下:使用上述模型,如果我收到来自 B 的请求,我希望在单个记录集中返回来自 A 的最新包和来自 C 的最新包,以及相关的传记信息. 我实际上对B不感兴趣!

我在这一点上取得的最好成绩涉及三个查询:

  1. 最初,检查用户表以获取我们用户的正确 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;
    

然后我将结果 1 和 2 合并到一个 PHP 数组中,并将这个数组的内容返回给提交请求的用户。在涉及许多此类请求的任何情况下,我都很难相信这种方法是有效的,更不用说理想了。尽管查询 2 和 3 实际上是相同的,并且我确信 WHERE 子句中的简单 OR 条件应该能够将它们组合起来,但如果不为我感兴趣的两个用户返回所有包,我就无法成功地做到这一点,或者,只返回一条记录,丢弃第二条(我显然错误地应用了时间约束)。例如,MySQL 抱怨我有时会错误地同时使用 UNION 和 ORDER BY 语句。每次我尝试修改它时,我都会把语法弄错。

我对我目前的解决方案真的很不满意,因为在这一点上看我的项目,这是我的服务器必须比其他所有任务更频繁地执行的单个 MySQL 任务。我确实意识到这个问题相当冗长,但我认为最好彻底解释一下,以便第一次可以理解。提前感谢您能给我的任何指导或方向。干杯。

4

1 回答 1

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
于 2012-07-02T23:19:33.650 回答