架构:
CREATE TABLE "items" (
"id" SERIAL NOT NULL PRIMARY KEY,
"country" VARCHAR(2) NOT NULL,
"created" TIMESTAMP WITH TIME ZONE NOT NULL,
"price" NUMERIC(11, 2) NOT NULL
);
CREATE TABLE "payments" (
"id" SERIAL NOT NULL PRIMARY KEY,
"created" TIMESTAMP WITH TIME ZONE NOT NULL,
"amount" NUMERIC(11, 2) NOT NULL,
"item_id" INTEGER NULL
);
CREATE TABLE "extras" (
"id" SERIAL NOT NULL PRIMARY KEY,
"created" TIMESTAMP WITH TIME ZONE NOT NULL,
"amount" NUMERIC(11, 2) NOT NULL,
"item_id" INTEGER NULL …
Run Code Online (Sandbox Code Playgroud) 架构:
CREATE TABLE "expenses_commissionrule" (
"id" serial NOT NULL PRIMARY KEY,
"country" varchar(2) NOT NULL,
"created" timestamp with time zone NOT NULL,
"modified" timestamp with time zone NOT NULL,
"activity" tsrange NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
说明:
我想创建一个应用程序来管理佣金计算。每个规则都有活动期。每个国家都有一套独立的规则。
约束:
第一的。为避免歧义,这些活动期不应重叠。我做了以下约束:
ALTER TABLE expenses_commissionrule
ADD CONSTRAINT non_overlapping_activity
EXCLUDE USING GIST (country WITH =, activity WITH &&);
Run Code Online (Sandbox Code Playgroud)
第二。在任何时间点都应该只有一个佣金规则,因此表中的间隔之间不应存在间隙。换句话说,所有区间的总和应该是 -INF:+INF。
问题:如何添加第二个约束?用例:我们有一个无限期的规则。我想切换到新规则,该规则应从下个月开始。在这种情况下,我想将当前规则结束期设置为当月月底,并在单个操作中添加新规则。
更新:将来我想添加以下行为:
换句话说,所有先前的约束都应仅应用于 user_id 为 NULL 的行。如何做到这一点?
PostgreSQL …
架构:
CREATE TABLE traffic_hit (
id SERIAL NOT NULL PRIMARY KEY,
country VARCHAR(2) NOT NULL,
created TIMESTAMP WITH TIME ZONE NOT NULL,
unique BOOLEAN NOT NULL,
user_agent_id INTEGER NULL
);
CREATE TABLE utils_useragent (
id SERIAL NOT NULL PRIMARY KEY,
user_agent_string TEXT NOT NULL UNIQUE,
is_robot BOOLEAN NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
初始查询:
SELECT
traffic_hit.created::DATE AS group_by,
COUNT(*) FILTER(WHERE traffic_hit.unique) AS unique_visits,
COUNT(*) AS non_unique_visits
FROM
traffic_hit
LEFT JOIN utils_useragent ON traffic_hit.user_agent_id = utils_useragent.id
WHERE
traffic_hit.created >= '2016-01-01' AND
traffic_hit.created …
Run Code Online (Sandbox Code Playgroud) 架构:
CREATE TABLE "applications" (
"id" SERIAL NOT NULL PRIMARY KEY,
"country" VARCHAR(2) NOT NULL,
"created" TIMESTAMP WITH TIME ZONE NOT NULL,
"is_preliminary" BOOLEAN NOT NULL,
"first_name" VARCHAR(128) NOT NULL,
"last_name" VARCHAR(128) NOT NULL,
"birth_number" VARCHAR(11) NULL
);
CREATE TABLE "persons" (
"id" UUID NOT NULL PRIMARY KEY,
"created" TIMESTAMP WITH TIME ZONE NOT NULL,
"modified" TIMESTAMP WITH TIME ZONE NOT NULL
);
ALTER TABLE "applications" ADD COLUMN "physical_person_id" UUID NULL;
CREATE INDEX "physical_person_id_idx" ON "applications" ("physical_person_id");
ALTER TABLE …
Run Code Online (Sandbox Code Playgroud) postgresql ×4
performance ×2
aggregate ×1
constraint ×1
index ×1
interval ×1
join ×1
subquery ×1