Используйте один столбец для группировки строк и минимум другого столбца для упорядочивания

Я использую клиент kysely для подключения к базе данных Postgres, но вы также можете предоставить решение на простом SQL.

Вы можете понять структуру базы данных, посмотрев на эту функцию миграции:

await db.schema
  .createTable("BigPaint")
  .addColumn("id", "uuid", (col) =>
    col
      .primaryKey()
      .defaultTo(sql`gen_random_uuid()`)
      .notNull(),
  )
  .addColumn("createdAt", "timestamptz", (col) =>
    col.defaultTo(sql`now()`).notNull(),
  )
  .addColumn("name", "text", (col) => col.notNull())
  .execute();

await db.schema
  .createTable("Inspiration")
  .addColumn("id", "uuid", (col) =>
    col
      .primaryKey()
      .defaultTo(sql`gen_random_uuid()`)
      .notNull(),
  )
  .addColumn("createdAt", "timestamptz", (col) =>
    col.defaultTo(sql`now()`).notNull(),
  )
  .addColumn("bigPaintId", "uuid", (col) =>
    col.references("BigPaint.id").onDelete("cascade").notNull(),
  )
  .addColumn("traitId", "uuid", (col) =>
    col.defaultTo(sql`gen_random_uuid()`).notNull(),
  )
  .addColumn("content", "text", (col) => col.notNull())
  .execute();

await db.schema
  .createIndex("Inspiration_bigPaintIdIndex")
  .on("Inspiration")
  .columns(["bigPaintId"])
  .execute();

await db.schema
  .createView("InspirationView")

Как видите, в последних строках кода я создаю представление. Я хочу, чтобы таблица Inspiration была переупорядочена следующим образом: строки должны быть упорядочены с помощью созданногоAt, но строки с одинаковым идентификатором типажа должны рассматриваться как одна строка, следовательно, одно значение созданногоAt. Я думаю, лучше объяснить это на примере упорядоченной таблицы.

содержание создано в идентификатор черты Тест 1 05.08.2024 фха Тест 4 30.08.2024 фха Тест 2 10.08.2024 джк Тест 3 15.08.2024 лм

Я пробовал разные запросы, используя with, partBy, orderBy, но мне удалось правильно упорядочить только в конце максимум по одному столбцу.

🤔 А знаете ли вы, что...
SQL поддерживает подзапросы (subqueries) для выполнения вложенных запросов.


53
1

Ответ:

Решено

Чтобы упорядочить минимум "createdAt" на группу одинаковых "traitId" без фактического агрегирования строк, используйте оконную функцию :

SELECT content, "createdAt", "traitId"
FROM   "Inspiration"
ORDER  BY min("createdAt") OVER (PARTITION BY "traitId"), "traitId", "createdAt", content;

Не обязательно включать одно и то же выражение в список SELECT.

Я добавил "traitId", "createdAt", content в качестве (необязательно) дополнительных ORDER BY выражений, чтобы разорвать связи и сделать порядок детерминированным.

Кроме того: избегайте этих идентификаторов со смешанным регистром, чтобы облегчить вашу жизнь с Postgres. Видеть: