0

我正在使用 MySQL 5 做一个项目。要求如下:

提供用户名、设备类型、操作系统版本和参与采摘的水果,其中用户拥有相同的设备类型,运行 iOS 4 或 4.1,并采摘相同的水果

相关表格如下:

用户:{ uID:INT,名称:VARCHAR(45),deviceOS:VARCHAR(45),deviceType:VARCHAR(45)}

选择:{ uID:INT,ts:TIMESTAMP,水果:VARCHAR(45)}

(粗体的主键。Pick 中的 uID 是 User 中 uID 的外键。)

我正在执行以下查询:

SELECT DISTINCT NAME1, OS1, DEV1, NAME2, OS2, DEV2, P1.fruit FROM Pick AS P1, Pick AS P2, 

(SELECT U1.uID AS User1, U1.name AS NAME1, U1.deviceOS AS OS1, U1.deviceType AS DEV1, 
        U2.uID AS User2, U2.name AS NAME2, U2.deviceOS AS OS2, U2.deviceType AS DEV2
FROM User AS U1, User AS U2 
WHERE (U1.uID != U2.uID) AND
      (U1.deviceType = U2.deviceType) AND
      (U1.deviceOS = "4" OR U1.deviceOS = "4.1") AND
      (U2.deviceOS = "4" OR U2.deviceOS = "4.1")) AS PartialResult

WHERE (P1.uID = PartialResult.User1) AND
      (P2.uID = PartialResult.User2) AND
      (P1.fruit = P2.fruit)

这将返回以下结果,但如您所见,它在某种程度上是“重复的”:

我尝试使用 GROUP BY fruit 来解决这个问题,但在一般情况下它不会返回正确的结果。限制 1 也不适用于一般情况。因此,经过数小时试图弄清楚这一点,我必须问:

有没有办法在一般情况下防止这种重复?

谢谢!

4

2 回答 2

4

而不是U1.uID != U2.uID,写U1.uID > U2.uID

于 2013-02-07T21:00:38.567 回答
2

您遇到的问题是每一行都将被复制,a--b并且b--a. 您需要某种方式来指定您只想要一个或另一个,但问题是,哪一个?您是否偏好 Priscilla 排在 Marcia 之前,反之亦然?

如果没有偏好,那么您可以制定一些仅允许其中一个或另一个通过的任意规则。例如,您可以比较名称并仅抓取第一个名称按字典顺序排列在第二个之前的行(请参见最后一行):

SELECT DISTINCT NAME1, OS1, DEV1, NAME2, OS2, DEV2, P1.fruit FROM Pick AS P1, Pick AS P2, 

(SELECT U1.uID AS User1, U1.name AS NAME1, U1.deviceOS AS OS1, U1.deviceType AS DEV1, 
        U2.uID AS User2, U2.name AS NAME2, U2.deviceOS AS OS2, U2.deviceType AS DEV2
FROM User AS U1, User AS U2 
WHERE (U1.uID != U2.uID) AND
      (U1.deviceType = U2.deviceType) AND
      (U1.deviceOS = "4" OR U1.deviceOS = "4.1") AND
      (U2.deviceOS = "4" OR U2.deviceOS = "4.1")) AS PartialResult

WHERE (P1.uID = PartialResult.User1) AND
      (P2.uID = PartialResult.User2) AND
      (P1.fruit = P2.fruit) AND
      (STRCMP(NAME1, NAME2) < 0)

当然,您可以实施任何您想要选择其中一个的规则。@igelkott 的答案通过强制 person 1'suID高于 person 2's 以同样的方式解决了这个问题uID,这是非常合理的(并且比进行字符串比较更快)。

于 2013-02-07T20:58:39.950 回答