AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 3259
Accepted
tostinni
tostinni
Asked: 2011-06-11 09:35:17 +0800 CST2011-06-11 09:35:17 +0800 CST 2011-06-11 09:35:17 +0800 CST

如何获得 A 列,其中 B 列按 C 列分组?

  • 772

我想获取具有最小“顺序”列的每个类别(我的分组列)的数据集的 ID。
这里用一组数据来说明我的想法:

CREATE TABLE DATAS (
    ID INT(2) ,
    CATEGORY INT(2) ,
    ORD INT(1) 
);

INSERT INTO DATAS (ID, CATEGORY, ORD)
VALUES (1, 1, 3), (2, 1, 2), (3, 1, 1), (4, 2, 1), (5, 2, 2);

预期结果:

ID   CATEGORY
-------------
3    1
4    2

奖金问题,即使“订单”列(ORD)有一些重复,如何只检索一个 ID?

INSERT INTO DATAS (ID, CATEGORY, ORD)
VALUES (1, 1, 3), (2, 1, 2), (3, 1, 1), (4, 2, 1), (5, 2, 1), (6, 3, NULL), (7, 3, NULL);

预期结果(例如使用 MIN 或其他建议):

ID   CATEGORY
-------------
3    1
4    2
6    3

欢迎使用 Oracle 或 MySQL 查询,非常感谢。

mysql oracle
  • 4 4 个回答
  • 551 Views

4 个回答

  • Voted
  1. Best Answer
    Leigh Riffel
    2011-06-11T12:09:48+08:002011-06-11T12:09:48+08:00

    Oracle解决这两个问题:

    SELECT ID, Category FROM (
       SELECT FIRST_VALUE(ID) OVER 
          (PARTITION BY Category ORDER BY Ord) IDOfSmallestOrdForCategory
          , Category, ID FROM DATAS
       )
       WHERE ID = IDOfSmallestOrdForCategory;
    

    这两个问题的通用解决方案:

    SELECT MIN(a.ID), a.Category FROM DATAS a
    JOIN (SELECT CATEGORY, COALESCE(MIN(ORD),0) MINORD FROM DATAS GROUP BY CATEGORY) b
    ON COALESCE(a.ORD,0) = b.MINORD AND a.Category = b.Category
    GROUP BY a.Category;
    

    甲骨文 DDL/DML:

    CREATE TABLE DATAS (
        ID       Integer,
        CATEGORY Integer,
        ORD      Integer 
    );
    
    INSERT INTO DATAS (ID, CATEGORY, ORD) VALUES (1, 1, 3);
    INSERT INTO DATAS (ID, CATEGORY, ORD) VALUES (2, 1, 2);
    INSERT INTO DATAS (ID, CATEGORY, ORD) VALUES (3, 1, 1);
    INSERT INTO DATAS (ID, CATEGORY, ORD) VALUES (4, 2, 1);
    INSERT INTO DATAS (ID, CATEGORY, ORD) VALUES (5, 2, 2);
    
    INSERT INTO DATAS (ID, CATEGORY, ORD) VALUES (1, 1, 3); 
    INSERT INTO DATAS (ID, CATEGORY, ORD) VALUES (2, 1, 2); 
    INSERT INTO DATAS (ID, CATEGORY, ORD) VALUES (3, 1, 1); 
    INSERT INTO DATAS (ID, CATEGORY, ORD) VALUES (4, 2, 1);
    INSERT INTO DATAS (ID, CATEGORY, ORD) VALUES (5, 2, 1); 
    INSERT INTO DATAS (ID, CATEGORY, ORD) VALUES (6, 3, NULL);
    INSERT INTO DATAS (ID, CATEGORY, ORD) VALUES (7, 3, NULL);
    
    • 6
  2. RolandoMySQLDBA
    2011-06-11T11:42:49+08:002011-06-11T11:42:49+08:00

    MySQL解决方案

    我想我明白了!!!!

    查询第一个答案:

    SELECT A.ID,A.CATEGORY FROM
    (SELECT ID,CATEGORY,ORD FROM DATAS GROUP BY ID,CATEGORY) A
    INNER JOIN
    (SELECT MIN(ORD) ORD FROM DATAS) B
    USING (ORD);
    

    查询第二个答案:

    SELECT AA.ID,AA.CATEGORY FROM
    (SELECT ID,CATEGORY,IFNULL(AAA.ORD,BBB.ORD) ORD FROM DATAS AAA,
    (SELECT MIN(ORD) ORD FROM DATAS) BBB) AA
    INNER JOIN
    (SELECT MIN(ORD) ORD FROM DATAS) BB
    USING (ORD)
    GROUP BY AA.CATEGORY,AA.ORD;
    

    第二个答案有点困难,因为我必须找到一种方法将 NULL 替换为最小 ORD 值。我希望这就是你想用 NULL 做的事情。如果您查看子查询 BBB,它包含最小 ORD 值。我在带有子查询 AAA 的笛卡尔积中使用它作为替换 NULL ORD 值的方法。在那之后剩下的就变得容易了。

    这是第一个查询运行的示例:

    mysql> use tostinni
    Database changed
    mysql> DROP TABLE IF EXISTS DATAS;
    Query OK, 0 rows affected, 1 warning (0.00 sec)
    
    mysql> CREATE TABLE DATAS (
        ->     ID INT(2) ,
        ->     CATEGORY INT(2) ,
        ->     ORD INT(1)
        -> );
    Query OK, 0 rows affected (0.06 sec)
    
    mysql> INSERT INTO DATAS (ID, CATEGORY, ORD) VALUES (1, 1, 3), (2, 1, 2), (3, 1, 1), (4, 2, 1), (5, 2, 2);
    Query OK, 5 rows affected (0.03 sec)
    Records: 5  Duplicates: 0  Warnings: 0
    
    mysql> SELECT * FROM DATAS;
    +------+----------+------+
    | ID   | CATEGORY | ORD  |
    +------+----------+------+
    |    1 |        1 |    3 |
    |    2 |        1 |    2 |
    |    3 |        1 |    1 |
    |    4 |        2 |    1 |
    |    5 |        2 |    2 |
    +------+----------+------+
    5 rows in set (0.00 sec)
    
    mysql> SELECT A.ID,A.CATEGORY FROM
        -> (SELECT ID,CATEGORY,ORD FROM DATAS GROUP BY ID,CATEGORY) A
        -> INNER JOIN
        -> (SELECT MIN(ORD) ORD FROM DATAS) B
        -> USING (ORD);
    +------+----------+
    | ID   | CATEGORY |
    +------+----------+
    |    3 |        1 |
    |    4 |        2 |
    +------+----------+
    2 rows in set (0.00 sec)
    
    mysql>
    

    这是第二个查询的示例运行:

    mysql> DROP TABLE IF EXISTS DATAS;
    Query OK, 0 rows affected (0.05 sec)
    
    mysql> CREATE TABLE DATAS (
        ->     ID INT(2) ,
        ->     CATEGORY INT(2) ,
        ->     ORD INT(1)
        -> );
    Query OK, 0 rows affected (0.08 sec)
    
    mysql> INSERT INTO DATAS (ID, CATEGORY, ORD)
        -> VALUES (1, 1, 3), (2, 1, 2), (3, 1, 1), (4, 2, 1), (5, 2, 1), (6, 3, NULL), (7, 3, NULL);
    Query OK, 7 rows affected (0.03 sec)
    Records: 7  Duplicates: 0  Warnings: 0
    
    mysql> SELECT * FROM DATAS;
    +------+----------+------+
    | ID   | CATEGORY | ORD  |
    +------+----------+------+
    |    1 |        1 |    3 |
    |    2 |        1 |    2 |
    |    3 |        1 |    1 |
    |    4 |        2 |    1 |
    |    5 |        2 |    1 |
    |    6 |        3 | NULL |
    |    7 |        3 | NULL |
    +------+----------+------+
    7 rows in set (0.00 sec)
    
    mysql> SELECT AA.ID,AA.CATEGORY FROM
        -> (SELECT ID,CATEGORY,IFNULL(AAA.ORD,BBB.ORD) ORD FROM DATAS AAA,(SELECT MIN(ORD) ORD
     FROM DATAS) BBB) AA
        -> INNER JOIN
        -> (SELECT MIN(ORD) ORD FROM DATAS) BB
        -> USING (ORD)
        -> GROUP BY AA.CATEGORY,AA.ORD;
    +------+----------+
    | ID   | CATEGORY |
    +------+----------+
    |    3 |        1 |
    |    4 |        2 |
    |    6 |        3 |
    +------+----------+
    3 rows in set (0.00 sec)
    
    mysql>
    

    试试看 !!!

    • 1
  3. tostinni
    2011-06-11T14:18:21+08:002011-06-11T14:18:21+08:00

    这是我的解决方案不如@Leigh 的优雅,但兼容 Oracle 和 MySQL ;)

    SELECT MIN(ID) AS ID, D1.CATEGORY
    FROM DATAS D1
    WHERE NOT EXISTS (
        SELECT NULL 
        FROM DATAS D2
        WHERE D2.CATEGORY = D1.CATEGORY
        AND D2.ID <> D1.ID 
        AND COALESCE(D2.ORD, 0 ) < COALESCE(D1.ORD, 0 ) 
    )
    GROUP BY D1.CATEGORY
    

    我不喜欢我必须添加一个GROUP BY来过滤重复的事实......

    • 0
  4. randomx
    2011-06-11T10:04:33+08:002011-06-11T10:04:33+08:00

    这将返回第一部分的答案:

    mysql> SELECT ID, CATEGORY, MIN(ORD) FROM DATAS GROUP BY CATEGORY;
    +------+----------+----------+
    | ID   | CATEGORY | MIN(ORD) |
    +------+----------+----------+
    |    1 |        1 |        1 |
    |    4 |        2 |        1 |
    |    6 |        3 |     NULL |
    +------+----------+----------+
    3 rows in set (0.00 sec)
    

    第二部分的答案有点复杂。你可能只想要一个答案,但你想要哪个答案?最强ID?最少类别?主观。否则这可能会这样做:

    mysql> SELECT * FROM (SELECT ID, CATEGORY, MIN(ORD) AS min FROM DATAS GROUP BY ID, CATEGORY) m GROUP BY min ORDER BY ID ASC;
    +------+----------+------+
    | ID   | CATEGORY | min  |
    +------+----------+------+
    |    1 |        1 |    3 |
    |    2 |        1 |    2 |
    |    3 |        1 |    1 |
    |    6 |        3 | NULL |
    +------+----------+------+
    4 rows in set (0.01 sec)
    
    • -1

相关问题

  • 是否有任何 MySQL 基准测试工具?[关闭]

  • 我在哪里可以找到mysql慢日志?

  • 如何优化大型数据库的 mysqldump?

  • 什么时候是使用 MariaDB 而不是 MySQL 的合适时机,为什么?

  • 组如何跟踪数据库架构更改?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    您如何显示在 Oracle 数据库上执行的 SQL?

    • 2 个回答
  • Marko Smith

    如何选择每组的第一行?

    • 6 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    我可以查看在 SQL Server 数据库上运行的历史查询吗?

    • 6 个回答
  • Marko Smith

    如何在 PostgreSQL 中使用 currval() 来获取最后插入的 id?

    • 10 个回答
  • Marko Smith

    如何在 Mac OS X 上运行 psql?

    • 11 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Marko Smith

    将数组参数传递给存储过程

    • 12 个回答
  • Martin Hope
    Manuel Leduc PostgreSQL 多列唯一约束和 NULL 值 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler 什么时候应该将主键声明为非聚集的? 2011-11-11 13:31:59 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    BrunoLM Guid vs INT - 哪个更好作为主键? 2011-01-05 23:46:34 +0800 CST
  • Martin Hope
    bernd_k 什么时候应该使用唯一约束而不是唯一索引? 2011-01-05 02:32:27 +0800 CST
  • Martin Hope
    Patrick 如何优化大型数据库的 mysqldump? 2011-01-04 13:13:48 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve