私は5つのテーブルを持っています:
顧客ID - 名前
p_orders id - id_customer - コード - 日付
p_items id - id_order - 説明 - 価格
h_orders と h_items は、p_orders と p_items の正確なコピーです。
p_ テーブルが大量の行に達すると、最も古いテーブルを h_ テーブルに移動します。
だから、私の問題は: p_ テーブルと h_ の両方からデータを取得し、それらを 1 つの一意のテーブルと見なす方法は?
たとえば、各顧客の注文数と (すべての顧客の注文の) 合計価格を取得したい場合、そのクエリを使用します。
SELECT
customer.id,
customer.name,
count(DISTINCT p_orders.id) AS num_orders,
sum(p_items.price) AS total_money
FROM
customer
INNER JOIN p_orders ON p_orders.id_customer = customer.id
INNER JOIN p_items ON p_items.id_order = p_orders.id
GROUP BY
customer.id,
customer.name,
p_orders.id_customer
ORDER BY
customer.id
テーブルの1つの「セット」(p_またはh_)でのみ機能しますが、両方が必要です。
UNION を使用しようとしました:
(
SELECT
customer.id,
customer.name,
count(DISTINCT p_orders.id) AS num_orders,
sum(p_items.price) AS total_money
FROM
customer
INNER JOIN p_orders ON p_orders.id_customer = customer.id
INNER JOIN p_items ON p_items.id_order = p_orders.id
GROUP BY
customer.id,
customer.name,
p_orders.id_customer
)
UNION
(
SELECT
customer.id,
customer.name,
count(DISTINCT h_orders.id) AS num_orders,
sum(h_items.price) AS total_money
FROM
customer
INNER JOIN h_orders ON h_orders.id_customer = customer.id
INNER JOIN h_items ON h_items.id_order = h_orders.id
GROUP BY
customer.id,
customer.name,
h_orders.id_customer
)
ORDER BY id ASC
これは機能しますが、顧客が p_ テーブルと h_ テーブルの両方に注文を持っている場合、その顧客には 2 つの異なる num_orders と total_money (それぞれ p_ テーブルと h_ テーブルから来る) を持つ 2 つの行があります。
ユニオンの外に GROUP BY id を追加しようとしました:
(
--SELECT 2
)
UNION
(
--SELECT 1
)
GROUP BY id
ORDER BY id ASC
しかし、クエリはERROR: syntax error at or near "GROUP" at character 948 で失敗し、 GROUP BY はそのように使用できないようです。
なにか提案を?
編集:
uriDium の場合、はい、すべてのテーブルに主キーとして id 列があり、参照されるフィールド (別名 p_orders.id_customer) も外部キーです。ここで、テスト用の db 構造ダンプ (テーブルの作成後にいくつかのインデックスと外部キーを追加しましたが、これが何かを意味するとは思いません):
CREATE TABLE customer (
id serial NOT NULL,
name character(50)
);
CREATE TABLE p_orders (
id serial NOT NULL,
id_customer integer NOT NULL,
date date DEFAULT now(),
code character(5)
);
CREATE TABLE p_items (
id serial NOT NULL,
id_order integer NOT NULL,
descr character(250),
price money
);
CREATE TABLE h_orders (
id integer NOT NULL,
id_customer integer NOT NULL,
date date,
code character(5)
);
CREATE TABLE h_items (
id integer NOT NULL,
id_order integer NOT NULL,
descr character(250),
price money
);
CREATE UNIQUE INDEX id_h_orders ON h_orders USING btree (id);
CREATE INDEX id_h_o_c ON h_orders USING btree (id_customer);
CREATE UNIQUE INDEX id_items_h ON h_items USING btree (id);
CREATE INDEX id_ordinr_dsve ON h_items USING btree (id_order);
ALTER TABLE ONLY customer
ADD CONSTRAINT customer_pkey (id);
ALTER TABLE ONLY p_orders
ADD CONSTRAINT p_orders_pkey PRIMARY KEY (id);
ALTER TABLE ONLY p_items
ADD CONSTRAINT p_items_pkey PRIMARY KEY (id);
ALTER TABLE ONLY stats
ADD CONSTRAINT stats_pkey PRIMARY KEY (id);
ALTER TABLE ONLY p_orders
ADD CONSTRAINT "$1" FOREIGN KEY (id_customer) REFERENCES customer(id) ON DELETE CASCADE;
ALTER TABLE ONLY p_items
ADD CONSTRAINT "$1" FOREIGN KEY (id_order) REFERENCES p_orders(id) ON DELETE CASCADE;
ALTER TABLE ONLY h_orders
ADD CONSTRAINT "$1" FOREIGN KEY (id_customer) REFERENCES customer(id) ON DELETE CASCADE;
ALTER TABLE ONLY h_items
ADD CONSTRAINT "$1" FOREIGN KEY (id_order) REFERENCES h_orders(id) ON DELETE CASCADE;