Oracle SQL order by不对多列进行排序

时间:2019-02-12 13:08:39

标签: sql oracle oracle11g oracle12c

我有一个表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企业版12.2.0.1.0版-64位生产版本0

PL / SQL版本12.2.0.1.0-生产0

CORE 12.2.0.1.0生产0

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

NLSRTL版本12.2.0.1.0-生产0

感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

以下是一些示例输入数据,希望可以使以下说明更清楚:

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  

这里有5条记录,它们告诉我们有用的信息,例如Albert Camus住在Carroll Street 300号,而Caroline Ahern住在Carroll St 200号。要了解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可以识别住在Carroll St 500号的Bertoldt Brecht。假设ORDER BY按照您期望的方式工作:居住在Carroll Street 100号的Albert Aherne的ID值是多少?


  

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

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

例如,我洗牌。现在,我请您拿五张牌,并将它们以升序排列(ace较低)。很简单。除了您画了七个黑桃和七个心。哪个先到?黑桃高于心脏,所以七颗心然后是七个黑桃。但是都在九家具乐部之前。

答案 1 :(得分: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

我建议您返回并查看表中的实际数据,这可能与您预期的不一样。

好运。