【问题标题】:PHP mysql Distinct, only load 1 set of idsPHP mysql Distinct,只加载1组id
【发布时间】:2011-12-21 16:22:58
【问题描述】:

我正在尝试获取顺序与唯一 ID 无关的数据。所以我的查询就是

SELECT DISTINCT id1, id2 FROM messages ORDER BY date

如果我有一个包含以下数据的数据库:

id1 | id2 | date
 5  |  6  |  1/2/2011
 6  |  5  |  1/1/2011

我只需要加载具有最新日期的列,因为 ID 是相同的 2 个人。真的,我必须在其中一个 id 是你的地方加载 id,所以我现在真正的查询是

SELECT DISTINCT userid_1, userid_2 
  FROM messages 
    WHERE userid_2=$dbid 
    OR userid_1=$dbid 
ORDER BY date

我得到[6 5] [5 9] [9 5] [5 15] [5 6] [5 17]的结果

结果 2 和 3 相同,1 和 5 相同。真的应该只查询 4 ​​个结果。谢谢!

【问题讨论】:

    标签: php mysql select distinct


    【解决方案1】:

    一个选项是:

    SELECT DISTINCT 
    if(userid_1 >= userid_2,userid_1, userid_2) AS 'id1', 
    if(userid_1 >= userid_2,userid_2, userid_1) AS 'id2'
    
    FROM messages 
    WHERE userid_2=$dbid OR userid_1=$dbid ORDER BY date
    
    1. 此查询显示每条记录的两个字段。
    2. 如果第一个字段大于或等于 userid2,则为 userid1,否则将显示 userid2
    3. 第二个字段的逻辑相反
    4. 这可确保两组相似的结果始终以相同的方式排序,因此DISTINCT 会将其视为相同。

    【讨论】:

    • 出于某种原因,如果我这样做,它会加载正确的行数,但实际上不会获得任何数据。它只显示 [][][][] ,其中应该显示正在加载的 id。 if($result > 0) { while($row = mysql_fetch_assoc($query)) { echo "[".$row['userid_1']." ".$row['userid_2']."] "; } }
    • nvm,忘了你需要把 [if(userid_1 >= userid_2,userid_1, userid_2)] 放在括号里。
    • 它工作得很好,但如果你不介意你能向我解释一下它是如何工作的,因为我不太确定我理解它。
    • 您可以在两个ifs 之后添加“AS userid_1”和“AS userid_2”,以“重命名”结果字段。
    • 不错。比我的数学复杂得多!
    【解决方案2】:

    如果您的目标是获得不同的配对,您可以执行以下操作以使较小的配对始终位于左列,较大的配对始终位于右侧,从而确保 distinct 起作用:

    SELECT DISTINCT
    (id1 - ( (id1 - id2) + abs(id1 - id2) ) * .5) as first,
    (id2 + ( (id1 - id2) + abs(id1 - id2) ) * .5) as second
    FROM messages ORDER BY date;
    

    由于对总是排列的,因此不需要任何配对功能。

    示例

    +------+------+--------+------------+
    | id1  | id2  | val    | pair_date  |
    +------+------+--------+------------+
    |    4 |    5 | test 1 | 2010-12-25 |
    |    5 |    4 | test 2 | 2011-10-31 |
    |   17 |   50 | test 3 | 2011-07-04 |
    |   50 |   17 | test 4 | 2001-01-01 |
    +------+------+--------+------------+
    

    如果我运行这个查询:

    SELECT DISTINCT 
       (id1 - ( (id1 - id2) + abs(id1 - id2) ) * .5) AS first, 
       (id2 + ( (id1 - id2) + abs(id1 - id2) ) * .5) AS second 
       FROM pairs ORDER BY pair_date;
    

    我明白了:

    +-------+--------+
    | first | second |
    +-------+--------+
    |   4.0 |    5.0 |
    |  17.0 |   50.0 |
    +-------+--------+
    2 rows in set (0.00 sec)
    

    显然使用布尔值具有相同的效果,更易于阅读,并且可能更快,但如果您只需要交换两个数字以使一侧始终较小,则上述算法很方便。

    我不确定您为什么会收到错误消息。我直接从 MySQL 命令行运行我的测试....

    【讨论】:

    • 谢谢,我已经得到它,但我把它放进去看看它是否也有效,它使 mysql_num_rows 错误了。我没有发现是哪个错误,因为我已经有了一种工作方式,我很好奇你的方法是否也能工作。我最终这样做的方式是“SELECT DISTINCT if(userid_1 >= userid_2,userid_1, userid_2), if(userid_1 >= userid_2,userid_2, userid_1) FROM messages WHERE userid_2=$dbid OR userid_1=$dbid ORDER BY date DESC "
    • 我确实测试过它,因为我知道这有点奇怪。有很多括号,留下了混淆的余地....此外,由于除以 2,这些值作为双精度值返回。另一件事是我的测试中实际上没有日期字段。我不认为这应该重要。我将添加一些并发布我的测试。
    • 感谢您试用它并给我反馈。让我知道它是否有效或派上用场。
    猜你喜欢
    • 2012-10-26
    • 2011-11-16
    • 2011-06-05
    • 1970-01-01
    • 1970-01-01
    • 2012-01-03
    • 2012-10-13
    • 1970-01-01
    相关资源
    最近更新 更多