【问题标题】:MySQL Select distinct values across multiple tablesMySQL 在多个表中选择不同的值
【发布时间】:2011-02-16 06:45:41
【问题描述】:

我有两张桌子:

table_1
uid | xid | name

table_2
uid | elements | time | pkey

我想选择多行 xid、元素和时间,其中时间是 10 个最小值并且 uid(或 xid)是不同的。

table_1中的uid,xid是唯一的,table_1和table_2中的uid是一对多的关系..

我尝试了类似的方法,但效果不太好:

SELECT table_1.xid, MIN(table_2.time), table_2.elements
FROM table_1, table_2
WHERE table_1.uid= table_2.uid
GROUP BY table_2.uid
LIMIT 10

让我们拿一些数据来玩:

table_1
uid | xid | name
1 | 435 | John
2 | 596 | Jane


table_2
uid | elements | time | pkey
1 | 1 | 567 | 0
2 | 2 | 335 | 1
1 | 1 | 435 | 2
1 | 2 | 456 | 3
2 | 1 | 337 | 4
1 | 1 | 428 | 5

如何为每个 UID 选择前 2 个不同的结果? 在这种情况下:

fid| elements | time
596| 2 | 335
435| 1 | 428

谢谢!!!

如果人们不明白为什么 lexu 的解决方案不起作用 - 它没有绑定到表 2 上的主键

如果我将上述数据更改为:

table_2
uid | elements | time | pkey
1 | 1 | 567 | 0
2 | 2 | 335 | 1
1 | 1 | 435 | 2
1 | 2 | 456 | 3
2 | 1 | 337 | 4
1 | 2 | 428 | 5

保持 table_1 相同,那么结果应该是:

fid| elements | time
596| 2 | 335
435| 2 | 428

但是@lexu的解决结果是:

fid| elements | time
596| 2 | 335
435| 1 | 428

不过,感谢大家的帮助,尤其是@eagle!

【问题讨论】:

  • 你没有忘记什么吗?这些表之间有什么联系? xid -> uid? JOIN + GROUP BY 不适合你吗?
  • uid -> uid..我会在上面解释更多..
  • 在 XID 上做你的小组 .. 然后它应该可以工作
  • 整个 table_2 中最小的 10 个或每个 uid 最小的 10 个或 table_2 中时间最短的 10 个 uid? :) 你必须精确地使用 SQL,然后它会变得容易得多:)
  • table_2 中不同 uid 的 10 个最小时间..

标签: mysql select distinct


【解决方案1】:

这是我的解决方案。我认为,与其只给出有效的查询,我将逐步完成我的思考过程和我在每个步骤中尝试过的查询:

首先,让我们为不同的uid 选择最小的 10 次:

select uid, min(time)
from table_2
group by uid
order by 2
limit 10

这给了我们:

uid | time
2 | 335
1 | 428

这很容易......不幸的是,这不允许我们获取主键,如果添加以下行,这将是一个问题:

table_2
uid | elements | time | pkey
1 | 2 | 428 | 6

在以后的查询中,当我们尝试加入 timeuid 时,我们将得到两条记录而不是 1 条。因此我们需要一个更好的查询来返回不同的值(例如 pkey)而不是 @ 987654327@,我假设它可能是不明显的......

注意:如果 MySQL 有 FIRST()LAST() 聚合函数,这会简单得多。不幸的是,事实并非如此,所以我们必须满足于子查询、order-by、limit 组合。

select
  t2.uid,
  (select pkey from table_2 t3 where t2.uid = t3.uid order by t3.time asc limit 1) as minpkey
from
  (select uid, min(time) from table_2 group by uid order by 2 limit 10) t2

这将返回我们可以使用的结果:

uid | minpkey
1 | 5
2 | 1

请注意,5 是随机选择的,而 6 也可以很容易地选择;这一切都取决于mysql如何决定选择它。但对我们来说,这并不重要。

接下来我们要显示更多数据(即xidelements 字段):

select t1.xid as fid, t5.elements, t5.time
from 
(select
  t2.uid,
  (select pkey from table_2 t3 where t2.uid = t3.uid order by t3.time asc limit 1) as minpkey
from
  (select uid, min(time) from table_2 group by uid order by 2 limit 10) t2
) t4
inner join table_1 t1 on (t4.uid = t1.uid)
inner join table_2 t5 on (t4.minpkey = t5.pkey)

还有 viola,它应该返回您在示例中提供的完全相同的数据!它可能效率不高,但应该可以!

【讨论】:

  • 谢谢 - 太好了 - 现在我想我需要看看我是否可以让我的表格更有效率或让我的查询更有效率!
猜你喜欢
  • 1970-01-01
  • 2018-07-31
  • 1970-01-01
  • 1970-01-01
  • 2016-05-03
  • 2011-06-01
  • 1970-01-01
  • 2012-07-03
  • 1970-01-01
相关资源
最近更新 更多