【问题标题】:Select max values from double joined table从双联表中选择最大值
【发布时间】:2019-01-07 13:16:06
【问题描述】:

在数据库中,我有三个表,例如:

+-----------------+--------+
| ident (PrimKey) | ident2 |
+-----------------+--------+
|             123 |    333 |
|             321 |    334 |
|             213 |    335 |
|            1234 |    336 |
+-----------------+--------+

+---------+----------+-------+-------+
| PrimKey | group_id | value | ident |
+---------+----------+-------+-------+
|       1 |        1 |    10 |   213 |
|       2 |        1 |     5 |   321 |
|       3 |        1 |    15 |  1234 |
|       4 |        1 |    10 |  1234 |
|       5 |        2 |     7 |   213 |
|       6 |        2 |    15 |   321 |
+---------+----------+-------+-------+

+---------+----------+----------+
| PrimKey | ident2_1 | ident2_2 |
+---------+----------+----------+
|       1 |      333 |      334 |
|       2 |      333 |      335 |
|       3 |      333 |      336 |
+---------+----------+----------+

第三张表是第一张表的两行之间的连接。第二个包含来自不同组的数据。

我必须从按 group_id 分组的第二个表中为第三个表中的特定用户连接行找到最大值。在示例 333 中。 正确答案应该是:

+----------+-------+-------+
| group_id | value | ident |
+----------+-------+-------+
|        1 |    15 |  1234 |
|        2 |    15 |   321 |
+----------+-------+-------+

但现在我已经对所有行进行了排序:

+----+----------+-------+-------+
|    | group_id | value | ident |
+----+----------+-------+-------+
|  1 |        1 |    15 |  1234 |
|  2 |        1 |    10 |   213 |
|  3 |        1 |     5 |   321 |
|  4 |        2 |    15 |   321 |
|  5 |        2 |    10 |  1234 |
|  6 |        2 |     7 |   213 |
+----+----------+-------+-------+

或者用不正确的 ident 纠正行

+----+----------+-------+-------+
|    | group_id | value | ident |
+----+----------+-------+-------+
|  1 |        1 |    15 |   213 |
|  2 |        2 |    15 |  1234 |
+----+----------+-------+-------+

sql 是:

DROP TABLE first;
DROP TABLE second;
DROP TABLE third;


CREATE TABLE first(group_id integer, value integer, ident integer);
CREATE TABLE second(ident integer, ident2 integer);
CREATE TABLE third(ident_1 integer, ident_2 integer);

INSERT INTO first VALUES(1, 10, 213);
INSERT INTO first VALUES(1, 5, 321);
INSERT INTO first VALUES(1, 15, 1234);

INSERT INTO first VALUES(2, 10, 1234);
INSERT INTO first VALUES(2, 7, 213);
INSERT INTO first VALUES(2, 15, 321);


INSERT INTO second VALUES(123, 333);
INSERT INTO second VALUES(321, 334);
INSERT INTO second VALUES(213, 335);
INSERT INTO second VALUES(1234, 336);

INSERT INTO third VALUES (333, 334);
INSERT INTO third VALUES (333, 335);
INSERT INTO third VALUES (333, 336);


SELECT f.group_id, max(f.value) as value, f.ident
FROM first as f
INNER JOIN second AS s ON f.ident = s.ident
INNER JOIN third AS t ON t.ident_2 = s.ident2
WHERE t.ident_1 = '333'
GROUP BY f.group_id
ORDER BY f.group_id ASC, f.value DESC;


SELECT f.group_id, f.value as value, f.ident
FROM first as f
INNER JOIN second AS s ON f.ident = s.ident
INNER JOIN third AS t ON t.ident_2 = s.ident2
WHERE t.ident_1 = '333'
ORDER BY f.group_id ASC, f.value DESC;

测试于:https://rextester.com/l/mysql_online_compiler

问候

编辑:

第三张表类似于朋友之间的联系,第二张表中有行。第一个表包含不同任务的分数,由 group_id 标识。我需要最好的朋友分数来完成不同的任务。所以我在第三张桌子上的朋友名单。我的分数来自第一个。此表之间的连接是第二个。

编辑2:

在第一个表中作为主键是 ident(PrimKey)。

作为主键的第二个和第三个只有另一列。

在第二列中,ident 列是连接到第一个表中的 ident (PrimKey) 的索引。

在第三个表中的列 ident2_1 和 ident2_2 是从第一个表连接到 indet2 的索引。

【问题讨论】:

  • 第一个和第三个表需要什么。详细说明问题
  • 在每种情况下,你能识别出PRIMARY KEY
  • 哪个 MySQL 版本?在 MySQL 8.0 中,许多事情变得更加简单。
  • 以下两种解决方案有效。支持并移动...这是一个链接:rextester.com/WWPK81904
  • 第二个表中是否存在 ident 123 的记录?接受的答案不考虑这种情况。

标签: mysql sql


【解决方案1】:

我想出了这个 SQL:

SELECT f.group_id, f.value as value, f.ident
FROM   first as f
INNER JOIN second AS s 
      ON f.ident = s.ident
INNER JOIN third AS t 
      ON t.ident_2 = s.ident2
WHERE t.ident_1 = '333'
and   f.value IN (  SELECT MAX(f1.value) 
                    FROM first as f1 
                    WHERE f1.group_id = f.group_id )
ORDER BY f.group_id ASC, f.value DESC;

【讨论】:

  • @Solus 如果您能批准答案,将不胜感激。
【解决方案2】:

肯定有一个更优雅的解决方案,但这会给出你想要的结果。

select m.*
from(
    select f.group_id, f.value value, f.ident
    from   first f,
           second s,
           third t
    where  f.ident = s.ident
    and    t.ident_2 = s.ident2
    and    t.ident_1 = '333'
    ORDER BY f.group_id ASC, f.value DESC ) m,
(
    select max(f.value) value
    from   first f,
           second s,
           third t
    where  f.ident = s.ident
    and    t.ident_2 = s.ident2
    and    t.ident_1 = '333' ) n
where m.value = n.value

这是第二种(也很笨拙)的技术,可以提供所需的结果:

select f.group_id, f.value value, f.ident
from   first f,
       second s,
       third t
where  f.ident = s.ident
and    t.ident_2 = s.ident2
and    t.ident_1 = '333'
and    value = (   select max(f.value) value
                   from   first f,
                          second s,
                          third t
                   where  f.ident = s.ident
                   and    t.ident_2 = s.ident2
                   and    t.ident_1 = '333' )
ORDER BY f.group_id ASC, f.value DESC 

【讨论】:

  • 非常感谢。这是否笨拙并不重要,但它是完美的起点。
  • 您不应该使用逗号分隔的连接。由于某种原因,他们在 1992 年被裁员。改为使用显式标准 ANSI 连接。
  • 真的是 1992 年吗? @ThorstenKettner 还没有弃用 ansi-89,据我所知,没有计划从 MySQL 中删除逗号分隔的连接。这是其他人的讨论:stackoverflow.com/questions/334201/…
猜你喜欢
  • 2011-12-14
  • 2020-05-28
  • 2014-06-17
  • 1970-01-01
  • 1970-01-01
  • 2014-10-06
  • 2012-03-16
  • 1970-01-01
  • 2013-10-20
相关资源
最近更新 更多