我正在使用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水果来解决这个问题,但它不会在一般情况下返回正确的结果。限制1也不适用于一般情况。因此,经过无数个小时试图解决这个问题,我必须问:
有没有办法在一般情况下防止这种重复?
谢谢!
答案 0 :(得分:4)
而不是U1.uID != U2.uID
,请写U1.uID > U2.uID
。
答案 1 :(得分: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的答案通过强制人1 uID
高于人2 uID
来解决问题,这是非常合理的(并且比进行字符串比较更快)。