在列上使用distinct并在另一列上执行order by会产生错误

时间:2012-01-18 06:01:20

标签: sql oracle sql-order-by distinct oracle9i

我有一张桌子:  abc_test,列为n_num,k_str。

此查询无效:

    select distinct(n_num) from abc_test order by(k_str)

但是这个有效:

    select n_num from abc_test order by(k_str)

DISTINCT和ORDER BY关键字如何在内部工作,以改变两个查询的输出?

11 个答案:

答案 0 :(得分:11)

据我所知,你的问题。

distinct: - 表示选择不同的(所有选定的值应该是唯一的)。 order by: - 只是意味着根据您的要求对所选行进行排序。

第一个查询中的问题是 例如 : 我有一张桌子

ID name
01 a
02 b
03 c
04 d 
04 a

现在查询select distinct(ID) from table order by (name)混淆了它应该为ID-04记录哪个记录(因为有两个值,d和a在Name列中)。所以当你说时,数据库引擎的问题就在这里  (姓名).........

答案 1 :(得分:4)

您可能会考虑使用group来代替:

select n_num
from abc_test
group by n_num
order by min(k_str)

答案 2 :(得分:3)

第一个查询是不可能的。 让我们举例解释一下。我们有这个测试:

n_num k_str
2     a
2     c
1     b

select distinct (n_num) from abc_test

2
1

Select n_num from abc_test order by k_str

2
1
2

您想要返回什么

select distinct (n_num) from abc_test order by k_str

它应该只返回1和2,但如何订购呢?

答案 3 :(得分:0)

您正在从查询的结果集中选择distinct(n_num)集合。因此,与列k_str不再存在实际关系。 n_num可以来自两行,每行具有不同的k_str值。所以你不能通过k_str命令集合distinct(n_num)。

答案 4 :(得分:0)

根据SQL标准,SELECT子句可以引用顶级SELECT子句中的子句(“别名”)或结果集按顺序位置的列,因此可以引用查询将符合要求。

与其他SQL实现一样,Oracle似乎允许您在SELECT子句中投影之前立即引用存在(逻辑上)的列。我不确定这种灵活性是否是一件好事:IMO最好通过在SELECT子句中包含列/表达式等来将排序顺序公开给调用应用程序。

与以往一样,您需要应用dsicpline才能获得有意义的结果。对于您的第一个查询,订单的定义可能完全是任意的。您应该感谢错误;)

答案 5 :(得分:0)

这种方法在SQL Server 2000中可用,您可以从表中选择不同的值,并按不同列中的不同列排序。 但在SQL 2012中,这将通过您的错误 “如果指定了SELECT DISTINCT,则ORDER BY项必须出现在选择列表中。”

因此,如果您想使用与SQL 2000相同的功能,您仍可以使用列号进行排序(在最佳实践中不建议这样做)。

select distinct(n_num) from abc_test order by 1

这将在获取结果后对第一列进行排序。如果您希望排序应该基于不同的列而不是distinct,那么您还必须在select语句中添加该列并使用列号来排序。

select distinct(n_num), k_str from abc_test order by 2

答案 6 :(得分:0)

扩展排序键列如何

第一个查询的logical order of operations in SQL为(简化):

  • FROM abc_test
  • SELECT n_num, k_str,即添加一个扩展的排序键列
  • ORDER BY k_str DESC
  • SELECT n_num,即再次从结果中删除扩展的排序键列

由于采用了SQL标准的扩展的排序键列功能,因此可以按SELECT子句中未包含的内容进行排序,因为该子句暂时被添加到了它的后面。在订购前先进行场景拍摄,然后在订购后再次删除。

那么,为什么DISTINCT不能使用?

如果我们添加DISTINCT操作,则需要在SELECTORDER BY之间添加该操作:

  • FROM abc_test
  • SELECT n_num, k_str,即添加一个扩展的排序键列
  • DISTINCT
  • ORDER BY k_str DESC
  • SELECT n_num,即再次从结果中删除扩展的排序键列

但是现在,有了扩展的排序键列 k_strDISTINCT操作的语义已更改,因此结果将不再相同。这不是我们想要的,因此SQL标准和所有合理的数据库都禁止这种用法。

解决方法

PostgreSQL具有DISTINCT ON语法,可以在此处使用它来完成这项工作:

SELECT DISTINCT ON (k_str) n_num
FROM abc_test
ORDER BY k_str DESC

如果您不使用PostgreSQL,则可以使用以下标准语法进行仿真

SELECT n_num
FROM (
  SELECT n_num, MIN(k_str) AS k_str
  FROM abc_test
  GROUP BY n_num
) t
ORDER BY k_str

或者,简单地(在这种情况下)

SELECT n_num, MIN(k_str) AS k_str
FROM abc_test
GROUP BY n_num
ORDER BY k_str

I have blogged about SQL DISTINCT and ORDER BY more in detail here

答案 7 :(得分:0)

我的查询与您的查询不完全匹配,但是非常接近。

select distinct a.character_01 , (select top 1 b.sort_order from LookupData b where a.character_01 = b.character_01 )
from LookupData a 
where 
Dataset_Name = 'Sample' and status = 200
order by 2, 1

答案 8 :(得分:-1)

你试过这个吗?

SELECT DISTINCT n_num as iResult
FROM abc_test 
ORDER BY iResult

答案 9 :(得分:-1)

你可以做到

aws cloudformation create-stack \
    --region us-east-1 \
    --stack-name MyStackName \
    --template-body file://MyTemplate.yaml

答案 10 :(得分:-1)

当我遇到同样的错误时,我通过将其更改为

来解决问题
SELECT n_num 
FROM(
   SELECT DISTINCT(n_num) AS n_num, k_str
   FROM abc_test
) as tbl
ORDER BY tbl.k_str