【发布时间】:2022-11-24 12:14:14
【问题描述】:
CREATE TYPE edition AS ENUM (
'b',
'j'
);
CREATE TABLE IF NOT EXISTS versions (
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
edition edition NOT NULL,
major integer NOT NULL,
minor integer NOT NULL,
patch integer NOT NULL,
cycle decimal GENERATED ALWAYS AS (
CAST(
(CAST(major AS text) || '.' || CAST(minor AS text)) AS decimal
)
) STORED
);
INSERT INTO versions
(edition, major, minor, patch)
VALUES
('b', 1, 16, 0),
('b', 1, 17, 0),
('b', 1, 18, 0),
('b', 1, 19, 0),
('j', 1, 16, 0),
('j', 1, 17, 0),
('j', 1, 18, 0),
('j', 1, 19, 0)
;
我正在构建一个 Web 应用程序来引用 Minecraft 的各个方面。我正在尝试在我的 versions 表中构建一个存储的生成列,以指定相关记录是否指定每个版本的最高版本号。 (Minecraft 作为两个独立且不兼容的版本发布:Bedrock (b) 和 Java (j)。)
鉴于上面的结构和数据,我希望以下选择对每个 is_latest_* 字段仅返回一次 true,对所有其他字段返回 false。
SELECT
*,
(
edition = 'b'
AND GREATEST(major) = major
AND GREATEST(minor) = minor
AND GREATEST(patch) = patch
) AS is_latest_bedrock,
(
edition = 'j'
AND GREATEST(major) = major
AND GREATEST(minor) = minor
AND GREATEST(patch) = patch
) AS is_latest_java
FROM versions
ORDER BY edition, major, minor, patch;
相反,我看到的是每条记录都被标记为每个版本的最高版本:
| id | edition | major | minor | patch | cycle | is_latest_bedrock | is_latest_java |
|---|---|---|---|---|---|---|---|
| ddcdc01f-7ac1-4c4a-be7f-5e93902a0855 | b | 1 | 16 | 0 | 1.16 | true | false |
| 20d1bf38-75d6-4d96-94fc-fd16d2131319 | b | 1 | 17 | 0 | 1.17 | true | false |
| 13252697-4fe6-411f-b151-e4a1ca146e2f | b | 1 | 18 | 0 | 1.18 | true | false |
| 16a1eb78-e566-4649-991c-3ecdd8e6f49b | b | 1 | 19 | 0 | 1.19 | true | false |
| 5ef4657a-c4fc-41f4-b2e1-0aa88e0e4b07 | j | 1 | 16 | 0 | 1.16 | false | true |
| f68cebf4-a62d-45c5-af67-098f8be041a3 | j | 1 | 17 | 0 | 1.17 | false | true |
| bd37ff94-5a62-4fc7-a729-6fc353a7c939 | j | 1 | 18 | 0 | 1.18 | false | true |
| 09293db6-aa6b-4cc4-8a58-29afba816d85 | j | 1 | 19 | 0 | 1.19 | false | true |
这是我期望/想要看到的结果集:
| id | edition | major | minor | patch | cycle | is_latest_bedrock | is_latest_java |
|---|---|---|---|---|---|---|---|
| ddcdc01f-7ac1-4c4a-be7f-5e93902a0855 | b | 1 | 16 | 0 | 1.16 | false | false |
| 20d1bf38-75d6-4d96-94fc-fd16d2131319 | b | 1 | 17 | 0 | 1.17 | false | false |
| 13252697-4fe6-411f-b151-e4a1ca146e2f | b | 1 | 18 | 0 | 1.18 | false | false |
| 16a1eb78-e566-4649-991c-3ecdd8e6f49b | b | 1 | 19 | 0 | 1.19 | true | false |
| 5ef4657a-c4fc-41f4-b2e1-0aa88e0e4b07 | j | 1 | 16 | 0 | 1.16 | false | false |
| f68cebf4-a62d-45c5-af67-098f8be041a3 | j | 1 | 17 | 0 | 1.17 | false | false |
| bd37ff94-5a62-4fc7-a729-6fc353a7c939 | j | 1 | 18 | 0 | 1.18 | false | false |
| 09293db6-aa6b-4cc4-8a58-29afba816d85 | j | 1 | 19 | 0 | 1.19 | false | true |
如何更新查询以仅将一个 Bedrock 版本和一个 Java 版本标记为最新?
【问题讨论】:
-
当您的数据包含自然复合键时,为什么要使用 UUID 作为 PK?
-
使用 MAX() 而不是 GREATEST。因此 MAX() 通常用于返回数据库中列中的最大值。该表可能包含许多行,但此函数返回具有最大值的行。另一方面,GREATEST() 从传递给它的参数列表中返回最大值参数。所以你可以给这个函数传递 3 个参数,它会返回具有最大值的那个。
标签: sql postgresql