2

我想得到

id   a    b     c
--------------------
1    1    100   90
6    2    50    100

...从:

id   a    b     c
--------------------
1    1    100   90
2    1    300   50
3    1    200   20
4    2    200   30
5    2    300   70
6    2    50    100

它是 b 组最小的行。

用sql怎么做?

编辑

我以为可以通过

select * from table group by a having min(b);

我后来发现这是错误的。

但是可以用having声明来做到这一点吗?

我正在使用 MySQL

4

5 回答 5

3
SELECT t1.*
FROM mytable t1
LEFT OUTER JOIN mytable t2
  ON (t1.a=t2.a AND t1.b>t2.b)
WHERE t2.a IS NULL;

这是有效的,因为不应该有t2相同a和较小的匹配行b


更新:此解决方案与其他人已确定的关系存在相同的问题。但是,我们可以打破关系:

SELECT t1.*
FROM mytable t1
LEFT OUTER JOIN mytable t2
  ON (t1.a=t2.a AND (t1.b>t2.b OR t1.b=t2.b AND t1.id>t2.id))
WHERE t2.a IS NULL;

例如,假设在平局的情况下,较低id的行应该是我们选择的行。


这不能解决问题:

select * from table group by a having min(b);

因为HAVING MIN(b)只测试组中的最小值不为假(在 MySQL 中表示不为零)。子句中的条件HAVING是从结果中排除组,而不是选择要返回的组中的行。

于 2009-12-25T06:30:30.153 回答
3

在 MySQL 中:

select t1.* from test as t1
inner join
(select t2.a, min(t2.b) as min_b from test as t2 group by t2.a) as subq
on subq.a=t1.a and subq.min_b=t1.b;

这是证明:

mysql> create table test (id int unsigned primary key auto_increment, a int unsigned not null, b int unsigned not null, c int unsigned not null) engine=innodb;
Query OK, 0 rows affected (0.55 sec)

mysql> insert into test (a,b,c) values (1,100,90), (1,300,50), (1,200,20), (2,200,30), (2,300,70), (2,50,100);
Query OK, 6 rows affected (0.39 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> select * from test;
+----+---+-----+-----+
| id | a | b   | c   |
+----+---+-----+-----+
|  1 | 1 | 100 |  90 |
|  2 | 1 | 300 |  50 |
|  3 | 1 | 200 |  20 |
|  4 | 2 | 200 |  30 |
|  5 | 2 | 300 |  70 |
|  6 | 2 |  50 | 100 |
+----+---+-----+-----+
6 rows in set (0.00 sec)

mysql> select t1.* from test as t1 inner join (select t2.a, min(t2.b) as min_b from test as t2 group by t2.a) as subq on subq.a=t1.a and subq.min_b=t1.b;
+----+---+-----+-----+
| id | a | b   | c   |
+----+---+-----+-----+
|  1 | 1 | 100 |  90 |
|  6 | 2 |  50 | 100 |
+----+---+-----+-----+
2 rows in set (0.00 sec)
于 2009-12-25T06:41:05.837 回答
1

采用:

SELECT DISTINCT
       x.*
  FROM TABLE x
  JOIN (SELECT t.a,
               MIN(t.b) 'min_b'
          FROM TABLE T
      GROUP BY t.a) y ON y.a = x.a
                     AND y.min_b = x.b
于 2009-12-25T06:36:35.300 回答
0

你是对的。select min(b), a from table group by a。如果您想要整行,那么您已经使用了分析功能。这取决于数据库软件。

于 2009-12-25T06:34:26.713 回答
0

这取决于实现,但这通常比自连接方法更快:

SELECT id, a, b, c
FROM
    (
        SELECT id, a, b, c
        , ROW_NUMBER() OVER(PARTITION BY a ORDER BY b ASC) AS [b IN a]
    ) As SubqueryA
WHERE [b IN a] = 1

当然,它确实要求您的 SQL 实现与标准保持同步。

于 2009-12-25T06:44:00.657 回答