【问题标题】:Unique rows from PostgreSQL database and orderingPostgreSQL 数据库中的唯一行和排序
【发布时间】:2018-02-20 11:59:47
【问题描述】:

如何从 PostgreSQL (8.4.20) 获取唯一行,此时我的查询如下所示:

SELECT 
    DISTINCT ON(student.id) student.id, 
    student.*,
    programme_stage.*
FROM  
    person AS student 
INNER JOIN 
    programme ON (student.id = programme.person_id) 
RIGHT JOIN 
    programme_stage ON (programme.id = programme_stage.programme_id) 
ORDER BY 
    student.id, 
    student.last_name ASC, 
    student.first_name ASC 
LIMIT 10 OFFSET 0

上面的查询可以正常工作,但我想按姓氏和名字的第一顺序排序。

样本数据:

| id | first_name | last_name | programme_id | programme_stage _id |
|----|------------|-----------|--------------|---------------------|
| 1  | Michał     | Nowak     | 1            | 1                   |
| 2  | Jan        | Kowalski  | 2            | 2                   |
| 3  | Tomasz     | Thomas    | 2            | 1                   |

预期输出:

| id | first_name | last_name | programme_id | programme_stage _id |
|----|------------|-----------|--------------|---------------------|
| 2  | Jan        | Kowalski  | 2            | 2                   |
| 1  | Michał     | Nowak     | 1            | 1                   |
| 3  | Tomasz     | Thomas    | 2            | 1                   |

如果我尝试从 order statment student.id 列中删除,我会收到错误:

..SELECT DISTINCT ON expressions must match the expressions .. ORDER BY LINE 2:  DISTINCT ON(student_person.id) student_person.id, 
                 ^

【问题讨论】:

  • 你真的还在用8.4吗?多年来,它已经不受支持
  • edit您的问题并添加一些sample data 和基于该数据的预期输出。 Formatted textno screen shots。 (edit 您的问题 - 在 cmets 中邮政编码或其他信息)
  • 如果从ORDER BY 子句中删除student.id 会怎样?

标签: sql postgresql sql-order-by distinct


【解决方案1】:

使用子查询:

SELECT s.*
FROM (SELECT DISTINCT ON (s.id) s.*, ps.*
      FROM programme_stage ps LEFT JOIN
           programme p
           ON programme.id = ps.programme_id LEFT JOIN
           person s
           ON s.id = p.person_id)
      ORDER BY s.id
      LIMIT 10 OFFSET 0
     ) s
ORDER BY s.last_name ASC, s.first_name ASC; 

注意事项:

  • 我更喜欢较短的表别名,这样查询更易于编写和阅读。
  • 比起RIGHT JOIN,我更喜欢LEFT JOIN。但是,由于您使用 person 表进行聚合,因此您可能需要内部联接。
  • 无需选择id 两次。
  • 如果列名称相同,您可能需要选择显式列而不是 *

【讨论】:

  • 我有大约 50 00 行,你的例子,只排序前 10 行(来自子查询):/
  • @JohnTemp 。 . . limit 10your 代码中。如果您想要所有行,请将其删除。
  • 我想按字母顺序对所有行(50 000)进行排序,然后获得前 10 个唯一记录。在您的示例中,首先获取前十行,并且仅对它们进行排序。
  • @JohnTemp 。 . .内连接按s.id 排序,这就是您的查询所做的。将order by 键更改为您想要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-13
  • 2021-06-19
  • 1970-01-01
  • 2011-11-24
  • 1970-01-01
  • 2018-11-17
  • 1970-01-01
相关资源
最近更新 更多