2012-07-18 47 views
0

是否有可能运行一个查询,并得到结果集A按年龄字段desc排序 然后查询结果A的任何记录,可以说一个颜色字段等于5 和组匹配字段,由高柱递减 对它们进行排序,并返回所有结果一次中:这是一个可能的子查询与标准的SQL

因此数据可能是这样的:

第1部分
age color height 
4 5  7 
3 6  1 
2 9  2 
6 5  3 

输出将产量(按年龄分类)

查询的最后一部分的
age color height 
6 5  1 
4 5  7 
3 6  2 
2 9  3 

输出将产生(子集等颜色,由高排序):

age color height 
4 5  7 
6 5  1 
3 6  2 
2 9  3 
+0

你的描述似乎不符合你的例子(年龄desc似乎与最终结果没有任何关系)。为什么按年龄排序呢? – Bruno 2012-07-18 21:24:31

+0

@Bruno - 显然,只有在有不同颜色的情况下,“age”的顺序才会下降,对于相同的顺序,它必须按照“height”排序。我知道,混淆 – Lamak 2012-07-18 21:25:52

+0

@Lamak,我想我理解你的意思,但这个例子有点混乱。仍然不知道如何从第一排到第二排。 6 5 1从哪里来? – Bruno 2012-07-18 22:35:42

回答

3

您的示例有点令人困惑,因为您可以通过使用ORDER BY color, height DESC(似乎行数太少)轻松实现相同的结果。

据我理解你的问题,你在每减少age第一反正排序真正感兴趣的,但你也想重新排列的一组具有相同color价值,如果他们是连续的,当排序行年龄。

您可以通过使用window functions(更具体地说,通过对结果进行分区)来实现所需的功能。这应该是"standard" SQL (SQL:2003),尽管它不会被所有的SQL RDMBS支持(据我所知,特别是不被MySQL支持)。

这里是PostgreSQL (8.4 or above)一个工作示例:

CREATE TABLE test_table(
    age INTEGER, 
    color INTEGER, 
    height INTEGER 
); 
INSERT INTO test_table(age, color, height) VALUES (7, 10, 1); 
INSERT INTO test_table(age, color, height) VALUES (6, 5, 1); 
INSERT INTO test_table(age, color, height) VALUES (5, 5, 10); 
INSERT INTO test_table(age, color, height) VALUES (4, 5, 7); 
INSERT INTO test_table(age, color, height) VALUES (3, 6, 2); 
INSERT INTO test_table(age, color, height) VALUES (2, 9, 3); 

查询(见SQL Fiddle for live demo):

WITH cte AS (
    SELECT age, color, height, 
      max(age) OVER (PARTITION BY color ORDER BY age DESC, color DESC) 
       AS maxage 
     FROM test_table 
) 
SELECT age, color, height FROM cte 
    ORDER BY maxage DESC, color, height; 

结果:

age | color | height 
-----+-------+-------- 
    7 | 10 |  1 
    6 |  5 |  1 
    4 |  5 |  7 
    5 |  5 |  10 
    3 |  6 |  2 
    2 |  9 |  3 

这样做是窗函数分配age的最大值为maxage分配给分区内的所有行(由color分区),最初由agecolor订购。

CTE的结果(这可能是一个子选择)是这样(见SQL Fiddle for live demo):

age | color | height | maxage 
-----+-------+--------+-------- 
    7 | 10 |  1 |  7 
    2 |  9 |  3 |  2 
    3 |  6 |  2 |  3 
    6 |  5 |  1 |  6 
    5 |  5 |  10 |  6 
    4 |  5 |  7 |  6 

这里,color分区之前每一行具有相同的maxage,当由有序在最终结果中,也保留了age的顺序,但允许您通过height来重新排序。

(在SQL小提琴快速测试,似乎表明这工作正常的MS SQL Server 2012和Oracle 11g R2太多; SQL Server 2008中似乎不喜欢在窗口定义MAXORDER BY。)

0

无需一个子查询 - 您可以使用二次(和三级等...)直接排序。

SELECT age, color, height 
FROM table 
ORDER BY color, height DESC 
0

你可以只指定一个副检索键搞定此行为:

SELECT * FROM table ORDER BY color, height DESC 

会产生:

age color height 
4 5  7 
6 5  1 
3 6  2 
2 9  3 
+0

是的,编辑来反映这一点。 – Oleksi 2012-07-18 21:21:54

+0

但是在这种情况下,'age'这个列的顺序是正确的,而不是强迫 – Lamak 2012-07-18 21:23:37

1

您可以通过调整用于为了通过标准做到这一点。

select t1.* 
from t1 
order by (case when color = 5 then height end) desc, 
     (case when coalesce(color, 0) <> 5 then age end) desc 

这首由排序下降高度,在颜色= 5,那么它按年龄,这些地方之间的颜色不5.聚结只是需要NULL值的护理组中。

被告诫说,以下不工作:

order by (case when color = 5 then height else age end) desc 

此合并了身高和年龄,和值可能会重叠。