多列的 MySQL Select 语句 DISTINCT

Posted

技术标签:

【中文标题】多列的 MySQL Select 语句 DISTINCT【英文标题】:MySQL Select Statement DISTINCT for Multiple Columns 【发布时间】:2009-07-25 06:24:10 【问题描述】:

我目前正在尝试构建一个有点棘手的 mysql Select 语句。这是我想要完成的任务:

我有一张这样的桌子:

data_table

uniqueID      stringID          subject
  1             144           "My Subject"
  2             144           "My Subject - New"
  3             144           "My Subject - Newest"
  4             211           "Some other column"

基本上,我想做的是能够通过 stringID 选择/分组(stringID 是线程的图片)而不是重复它。此外,我想选择最近的 stringID 行,(在上面的示例中是 uniqueID 3)。

因此,如果我要查询数据库,它将返回以下内容(最近的唯一 ID 在顶部):

uniqueID   stringID    subject
 4          211        "Some other column"  
 3          144        "My Subject - Newest" //Notice this is the most recent and distinct stringID row, with the proper subject column.

我希望这是有道理的。谢谢你的帮助。

【问题讨论】:

您是否 100% 确定 uniqueID 将始终是表中的最高 ID?如果没有,我建议你添加一个最新的时间戳 我实际上确实有一个时间戳列(不包括在我上面的示例中)。那么,我将如何使用我的时间戳列呢? MAX 是否适用于时间戳列?谢谢。 【参考方案1】:

试试下面的。它可能不是最有效的查询,但它会起作用:

SELECT uniqueID, stringID, subject
FROM data_table
WHERE uniqueID IN
 (
  SELECT MAX(uniqueID) 
  FROM data_table
  GROUP BY stringID
 )
ORDER BY uniqueID DESC

【讨论】:

这个查询帮助最大。此外,我使用时间戳将 'uniqueID' 替换为上面 lexu 的建议。非常感谢您的帮助。 我发现这个正在寻找类似问题的解决方案。这是一个很好的解决方案,但是使用临时表代替子选择可以提高性能。根据子选择创建一个临时表,然后在主查询中的子选择所在的位置,将 select * from temp table 放在它的位置。在我的 80000+ 行数据集上,subselect 方法需要几分钟才能运行,而使用临时表则需要大约 15 秒。【参考方案2】:
SELECT DISTINCT(a),
  ( SELECT DISTINCT(b) ) AS b,
  ( SELECT DISTINCT(c) ) AS c

FROM tblMyTBL

WHERE...
Order By...
Etc.

【讨论】:

【参考方案3】:

编辑:根据 OP 在评论中提供的新信息,这比依赖 uniqueID 更好:

select t.uniqueID
       , t.stringID
       , t.subject
       , t.your_timestamp_col
from   data_table t
       left outer join data_table t2
       on t.stringID = t2.stringID
    and
       t2.your_timestamp_col > t.your_timestamp_col
where  t2.uniqueID is null

如果正如 lexu 在评论中提到的那样,您确定最高的 uniqueID 值始终与最新的主题相对应,您可以这样做:

select t.uniqueID
       , t.stringID
       , t.subject
from   data_table t
       left outer join data_table t2
       on t.stringID = t2.stringID
    and
       t2.uniqueID > t.uniqueID
where  t2.uniqueID is null

这基本上意味着:只将data_table 中不存在更高uniqueID 值的记录返回给我。

【讨论】:

它实际上会表现得更差。子查询不使用任何超级查询列,因此只计算一次。 max 比尝试逐个比较每个 id 快得多。此外,连接必须应用where 子句。然而,子查询将创建一个哈希表,用作对每个 ID 的查找。因此,只有一个比较,所有的比较完成后我们不必检查列。 @Eric - 你的论点有道理,但unfortunately MySQL doesn't currently work that way【参考方案4】:

我遇到了类似的情况,但发现了一个不同的查询。试试这个:

SELECT MAX(uniqueID), stringID, subject
 FROM data_table
 GROUP BY stringID

【讨论】:

在提供解决问题的代码时,最好也至少简短地解释一下它是如何工作的,这样阅读的人就不必逐行精神分析来理解差异.【参考方案5】:
private void LoadAllFamilyMembers(string relationShip)
        
            lbFamilyMembers.SelectedIndexChanged -= new EventHandler(lbFamilyMembers_SelectedIndexChanged);
            SqlCommand cmd = new SqlCommand("select familymemberid,name from FamilyMembers where relationship = @relationship", con);
            cmd.Parameters.AddWithValue("@relationship", relationShip);
            DataTable dt = new DataTable();
            SqlDataAdapter adapter = new SqlDataAdapter(cmd);
            adapter.Fill(dt);
            lbFamilyMembers.DataSource = dt;
            lbFamilyMembers.DisplayMember = "name";
            lbFamilyMembers.ValueMember = "familymemberid";
            lbFamilyMembers.SelectedIndex = -1;
            lbFamilyMembers.SelectedIndexChanged += new EventHandler(lbFamilyMembers_SelectedIndexChanged);
        

【讨论】:

以上是关于多列的 MySQL Select 语句 DISTINCT的主要内容,如果未能解决你的问题,请参考以下文章

MySQL_select distinct无法实现只对单列去重,并显示多列结果的解决方法

Mysql高手系列 - 第12篇:子查询详解

MySQL:查询修改

MySQL SELECT DISTINCT 多列

mysql 索引

mysql 索引