【问题标题】:Oracle SQL order by doesn't order multiple columnsOracle SQL order by 不会对多列进行排序
【发布时间】:2019-07-06 03:28:07
【问题描述】:

我有一个表student,我想对其中的三列进行排序:first_name, last_name, street_address。我期待这样的结果:

| first_name | last_name | street_address |

     A            A        100 Carroll St
     B            B        200 Carroll St
     C            C        300 Carroll St

这是我的 SQL 查询:

SELECT first_name, last_name, street_address
FROM student
ORDER BY first_name, last_name, street_address;

但是这个查询是这样排序的:

| first_name | last_name        | street_address            |

     A         C (not sorted)       300 Carroll St  (not sorted)
     B         B (not sorted)       100 Carroll St  (not sorted)
     C         A (not sorted)       200 Carroll St  (not sorted)

此查询无法正常工作。它不会按升序对所有列进行排序,它只对出现在 ORDER BY 之后的第一列进行排序。如上所述,查询只对first_name 列进行排序。如果我在 ORDER BY 之后更改列的位置,它只会在“ORDER_BY”之后对第一个提到的列进行排序。

我搜索了 Google 和许多论坛,但找不到与此问题相关的任何内容。

Oracle 版本:

Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production 0

PL/SQL 版本 12.2.0.1.0 - 生产 0

核心 12.2.0.1.0 生产 0

适用于 64 位 Windows 的 TNS:版本 12.2.0.1.0 - 生产 0

NLSRTL 版本 12.2.0.1.0 - 生产 0

感谢您的帮助。

【问题讨论】:

  • order by 就是这样工作的。键是按顺序使用的,并且仅用于打破前面键中的关系。
  • 完全符合预期。首先按 first_name 排序。在重复的情况下按姓氏排序。等等。
  • 这些不是独立的值;列属于行,因此您不能将名字与姓氏与街道地址分开排序。嗯,你可以,但问题是这样的数据代表什么。
  • 这就是 order by 的工作方式......
  • @APC 啊,是的,好点,重新阅读问题,我将删除该评论

标签: sql oracle oracle11g oracle12c


【解决方案1】:

您给出的查询不会给出您所说的结果。你会得到什么

A   A   100 Carroll St
B   B   200 Carroll St
C   C   300 Carroll St

使用以下查询

WITH student AS (SELECT 'A' AS FIRST_NAME, 'A' AS LAST_NAME, '100 Carroll St' AS STREET_ADDRESS FROM DUAL UNION ALL
                 SELECT 'B', 'B', '200 Carroll St' FROM DUAL UNION ALL
                 SELECT 'C', 'C', '300 Carroll St' FROM DUAL)
SELECT first_name, last_name, street_address
FROM student
ORDER BY first_name, last_name, street_address

我建议你回去看看表格中的实际数据,这可能不是你所期望的。

祝你好运。

【讨论】:

    【解决方案2】:

    这里是一些示例输入数据,希望能让下面的解释更清楚:

    id  | first_name | last_name    | street_address         
     10 | Albert     |  Camus       | 300 Carroll St 
     20 | Caroline   |  Aherne      | 200 Carroll St 
     30 | Bertoldt   |  Brecht      | 500 Carroll St  
     40 | Albert     |  Dumbledore  | 400 Carroll St 
     50 | Bertoldt   |  Brecht      | 100 Carroll St  
    

    这里有五个记录,它们告诉我们有用的信息,例如 Albert Camus 住在 300 Carroll Street 和 Caroline Ahern 住在 200 Carroll St。了解 SQL 查询的重要一点是它检索记录;当我们使用 ORDER BY 时,它对记录进行排序,而不是对各个列进行排序。

    因此,当我们按first_name, last_name, street_address 排序这些记录时,我们会得到以下结果:

    id  | first_name | last_name    | street_address         
     10 | Albert     |  Camus       | 300 Carroll St 
     40 | Albert     |  Dumbledore  | 400 Carroll St 
     50 | Bertoldt   |  Brecht      | 100 Carroll St  
     30 | Bertoldt   |  Brecht      | 500 Carroll St 
     20 | Caroline   |  Aherne      | 200 Carroll St  
    

    结果集是按first_name顺序排序的表记录;当两条记录具有相同的值first_name 时,排序使用last_name 打破平局;当first_namelast_name 相同时,排序使用street_address。这正是我们所期望的。记录保持不变。

    对列进行独立排序意味着什么?卡罗尔街 100 号没有阿尔伯特·阿赫恩这样的人。那么 SQL 将如何组成一个呢?

    如果您仍然无法理解它的工作方式,请注意我在表中添加了代理主键。 ID 列唯一标识每条记录。因此,ID = 30 表示居住在卡罗尔街 500 号的 Bertoldt Brecht。假设 ORDER BY 以您期望的方式工作:对于居住在卡罗尔街 100 号的 Albert Aherne,ID 的价值是多少?


    根据规范化形式,在一个表中,所有记录都必须与主键相关,这意味着您不能对多列进行排序,那么为什么我们需要对多列进行排序?

    规范化与它无关。我们可能希望按复合键的列甚至非键属性进行排序。在这种情况下,我们经常需要按多列排序。

    例如,我洗一副牌。现在我请你拿五张牌,按升序排列,A 低。很容易。除了你画了黑桃七和红心七。哪个先出现?黑桃比红桃高,所以红桃七然后是黑桃七。但都在九家具乐部之前。

    【讨论】:

    • 感谢您的回答。现在我很清楚了。我没有逻辑思考。但是还有另一个问题,我们可以使用对多列进行排序。根据规范化的形式,在一张表中,所有记录都必须与主键相关,这意味着你不能对多列进行排序,那为什么我们需要对多列进行排序呢?
    • 扩展了我的答案以解决您的后续问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-07
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多