6

假设我想编写一个SELECT使用 a 的简单查询VIEW

CREATE TEMP VIEW people AS
SELECT 
     p.person_id
    ,p.full_name
    ,p.phone
FROM person p
ORDER BY p.last_name;

SELECT
     p.*
    ,h.address
    ,h.appraisal
FROM people p
LEFT JOIN homes h
     ON h.person_id = p.person_id
ORDER BY p.last_name, h.appraisal;

这里明显的问题是p.last_name当我去执行 final 时不再可用ORDER BY

如何对最终查询进行排序,以便people视图的原始序列遵循最终查询?

这里的简单解决方案是在视图中包含 p.last_name。我不想那样做——我在现实世界中的例子(要复杂得多)使这成为一个问题。

我过去对临时表做过类似的事情。例如,我使用创建表,CREATE TEMP TABLE testing WITH OIDS然后执行一个ORDER BY testing.oid以通过原始序列。

是否可以对视图做同样的事情?

4

3 回答 3

5

如果您使用row_number() over().

这是一个例子:

SELECT
    p.*
    ,h.address
    ,h.appraisal
FROM (SELECT *, row_number() over() rn FROM people) p
LEFT JOIN homes h
    ON h.person_id = p.person_id
ORDER BY p.rn, h.appraisal;

这是您可以测试的SQL Fiddle 。

正如@Erwin Brandstetter 正确指出的那样,使用rank()将产生正确的结果并允许对其他字段进行排序(在本例中为评估)。

SELECT
    p.*
    ,h.address
    ,h.appraisal
FROM (SELECT *, rank() over() rn FROM people) p
LEFT JOIN homes h
    ON h.person_id = p.person_id
ORDER BY p.rn, h.appraisal;

以这种方式考虑,使用 row_number(),它将始终仅按该字段排序,而不管任何其他排序参数。通过使用相同关系的 rank(),可以轻松搜索其他字段。

祝你好运。

于 2013-01-31T23:29:17.807 回答
3

基于@sgeddes 的想法,但rank()改用:

SELECT p.*
      ,h.address
      ,h.appraisal
FROM  (SELECT *, rank() OVER() AS rn FROM people) p
LEFT  JOIN homes h ON h.person_id = p.person_id
ORDER BY p.rn, h.appraisal;

我提供了一个测试用例来证明差异。
-> sqlfiddle

于 2013-02-01T00:25:17.247 回答
1

创建一个 row_number 列并在选择中使用它。

CREATE TEMP VIEW people AS
SELECT 
     row_number() over(order by p.last_name) as i
    ,p.person_id
    ,p.full_name
    ,p.phone
FROM person p

SELECT
     p.*
    ,h.address
    ,h.appraisal
FROM people p
LEFT JOIN homes h
     ON h.person_id = p.person_id
ORDER BY p.i, h.appraisal
于 2013-01-31T23:29:10.087 回答