2009-08-19 115 views
2

所以我的语法在所有三种情况下显然是正确的(PostgreSQL并没有对任何东西感兴趣),但结果以所有这三种查询的相同顺序返回。甚至更奇怪的是,当我从下面的任何一个添加/删除DESC时,它也没有影响。是否可以根据子查询的元素对结果进行排序?子查询和排序? (ORDER BY)

Sort by affiliation 
SELECT * FROM articles_view WHERE (1=1) 
AND spubid IN 
    (SELECT people.spubid FROM people WHERE (people.slast ilike 'doe') 
    GROUP BY people.spubid, people.slast, people.saffil) 
AND spubid IN 
    (SELECT status.spubid FROM status WHERE ((status.imonth >= 01 OR status.imonth IS NULL) AND status.iyear >= 2000) AND ((status.imonth <= 01 OR status.imonth IS NULL) AND status.iyear <= 2008) ORDER BY status.iyear, status.imonth) 

Sort by last name, descending order 
SELECT * FROM articles_view WHERE (1=1) 
AND spubid IN 
    (SELECT people.spubid FROM people WHERE (people.slast ilike 'doe') 
    GROUP BY people.spubid, people.slast, people.saffil ORDER BY people.slast DESC) 
AND spubid IN 
    (SELECT status.spubid FROM status WHERE ((status.imonth >= 01 OR status.imonth IS NULL) AND status.iyear >= 2000) AND ((status.imonth <= 01 OR status.imonth IS NULL) AND status.iyear <= 2008)) 

Sort by year/month descending order 
SELECT * FROM articles_view WHERE (1=1) 
AND spubid IN 
    (SELECT people.spubid FROM people WHERE (people.slast ilike 'doe') 
    GROUP BY people.spubid, people.slast, people.saffil) 
AND spubid IN 
    (SELECT status.spubid FROM status WHERE ((status.imonth >= 01 OR status.imonth IS NULL) AND status.iyear >= 2000) AND ((status.imonth <= 01 OR status.imonth IS NULL) AND status.iyear <= 2008) ORDER BY status.iyear, status.imonth DESC) 

我只是不确定为什么ORDER BY条件对结果顺序没有影响。

********* UPDATE:

我最终什么事是使用阵列列在我看来,(在这种情况下articles_view)做我的所有排序做。这样我就可以在主要查询中的“列”上完成所有工作,完全避免使用JOINS。定义视图的方式是,所有与人员/状态表中的给定pubid(主键)匹配的列(都具有1->多个)存储在视图中的数组列中。我与排序查询看起来是这样的:

SELECT * FROM articles_view WHERE 
    ((articles_view.skeywords_auto ilike '%ice%') OR (articles_view.skeywords_manual ilike '%ice%')) 
    ORDER BY (articles_view.authors[1]).slast 

这部作品的原因是因为我总是知道该数组的第一个成员(从Postgres第一指数为1,而不是通常0),是主要的作者(或主要地位),这是我需要排序。

回答

0

我最终什么事是使用阵列列在我看来,这样做(在这案例articles_view)做我所有的排序。这样我就可以在主要查询中的“列”上完成所有工作,完全避免使用JOINS。定义视图的方式是,所有与人员/状态表中的给定pubid(主键)匹配的列(都具有1->多个)存储在视图中的数组列中。我与排序查询看起来是这样的:

SELECT * FROM articles_view WHERE 
    ((articles_view.skeywords_auto ilike '%ice%') OR (articles_view.skeywords_manual ilike '%ice%')) 
    ORDER BY (articles_view.authors[1]).slast 

这部作品的原因是因为我总是知道该数组的第一个成员(从Postgres第一指数为1,而不是通常0),是主要的作者(或主要地位),这是我需要排序。

3

所有子查询都在做的是提供一组结果来检查spubid是否存在。您需要实际加入状态表,然后使用外部查询中的order by子句中的列。

喜欢的东西:

SELECT * 
FROM articles_view 
     INNER JOIN status ON articles_view.spubid = status.spubid 
     INNER JOIN people ON articles_view.spubid = people.spubid 
WHERE ((status.imonth >= 01 OR status.imonth IS NULL) AND status.iyear >= 2000) 
     AND ((status.imonth <= 01 OR status.imonth IS NULL) 
     AND status.iyear <= 2008 AND people.slast ilike 'doe') 
ORDER BY status.iyear, status.imonth 
+0

呃这就是我害怕的,我真的想避免使用连接(产品会变得太大,因此使用子查询来代替)。 – 2009-08-19 23:23:08

+0

使用内部联接您只会得到合适的结果,并且查询优化器应该确定一个计划,在应用联接之前删除不满足where子句的任何内容。 – 2009-08-19 23:30:25

1

你只是排序所使用的陈述中的数据。您需要对顶级Select语句进行排序。

编辑:

而且,由于IN子句内的SELECT语句无助于你的结果的总体排序,你应该从他们的条款删除订单,从而防止服务器不必做不必要的处理。

2

你不订货查询;您只需订购内部查询。这是完全合法的,但所有你与那些内部结果来比较spubid反对他们这样做,它也没有多少,不管你做什么样的顺序,在。

什么你要找的是一个JOIN

SELECT * 
FROM articles_view 
INNER JOIN status ON (status.spubid = articles_view.spubid AND ((status.imonth >= 01 OR status.imonth IS NULL) AND status.iyear >= 2000) AND ((status.imonth <= 01 OR status.imonth IS NULL) AND status.iyear <= 2008)) 
WHERE spubid IN 
    (SELECT people.spubid FROM people WHERE (people.slast ilike 'doe') 
    GROUP BY people.spubid, people.slast, people.saffil) 
ORDER BY status.iyear, status.imonth DESC 

(你可以重写其他查询作为也加入,但为了简单起见,我离开了独自一人。)

+0

因为我不知道用户是否想要在人员或状态表中的字段上进行排序,所以我将不得不加入。问题在于我留下的产品,只需要将这么多数据纳入查询中,但听起来像这是我唯一的选择,如果我想允许各种排序选项。 – 2009-08-19 23:32:11

+1

无论您是否加入JOIN,您都将这么多数据纳入查询*处理。如果你的担心是简单地返回那么多*列*,那么*很容易*纠正:只需要'SELECT articles_view。*'而不是'SELECT *' – VoteyDisciple 2009-08-19 23:51:50