SQL:그룹 2 이블로 1 조 동맹의하십니까?
문제
나는 5tables:
고객 id-름
p_orders id-id_customer-코드 날짜
p_items id-id_order-설명-가격
고 h_orders 및 h_items,정확히의 사본 p_orders 및 p_items.
때 p_ 테이블 도달의 큰 금액을 행,이동 가장 오래된 h_ 테이블..그들은 때로는 역사.
그래서 내 문제입니다: 를 검색하는 방법 모두에서 데이터를 p_ 테이블과 h_ 고려하면 그들 중 하나로 고유한 테이블?
예를 들어,나를 검색하려는 수의 주문한 각각의 고객과의 총 가격(의 모든 고객의 주문고),내가 사용하는 쿼리:
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
그것은 작품이 단지 하나의'설정'의 테이블(p_ 또는 h_).그러나 나는 그들 모두.
나는 선택을 사용하는 유니온:
(
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 개의 행하는 고객과 다른 2num_orders 및 total_money(각각에서 오는 p_ 테이블과 h_ 테이블)
나는 선택을 추가하여 그룹 id 외부 연합:
(
--SELECT 2
)
UNION
(
--SELECT 1
)
GROUP BY id
ORDER BY id ASC
하지만 쿼리 실패로 오류:구문 오류가 발생하거나"그룹에"문자 948, 것과 같은 그룹에 의해서 사용할 수 없습니다.
어떤 제안이 있으십니까?
편집:
에 대한 uriDium,그렇다,모든 테이블의 id 열로 기본 키가 언급된 필드(aka 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;
해결책
두 테이블 위에 뷰를 만들어야 할 것입니다.
CREATE VIEW All_Orders
AS
SELECT
id,
id_customer,
code,
date,
'H' AS order_type
FROM
h_orders
UNION ALL
SELECT
id,
id_customer,
code,
date,
'P' AS order_type
FROM
p_orders
CREATE VIEW All_Order_Items -- A table name of "items" is pretty bad in my opinion
AS
SELECT
id,
id_order,
description,
price,
'H' AS order_item_type
FROM
h_items
UNION ALL
SELECT
id,
id_order,
description,
price,
'P' AS order_item_type
FROM
p_items
이제 그 견해에 참여할 수 있습니다. "ID"열이 무엇인지 알 수 있도록 유형 (P & H)을 포함 시켰습니다. 두 테이블의 ID ( "h"및 "p"가 복제를 가질 수 있다면 All_order_items보기에서 주문 테이블에 바로 결합해야합니다. 그렇지 않으면 두 뷰 사이에 많은 어려움을 겪게됩니다. 열은 지능적으로 설계되었으며 자동 침입 또는 아이덴티티 열뿐만 아니라.
다른 팁
당신은 이것을 시도 할 수 있습니다 :
SELECT tbl.ID,
tbl.Name,
sum(tbl.num_orders) num_orders,
sum(tbl.total_money) total_money
FROM (
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
) tbl
GROUB BY tbl.id, tbl.name
ORDER BY tbl.id ASC
두 쿼리의 결합이지만 집계 함수가없는 시야를 만듭니다. 동일한 레코드가 두 테이블에 있지 않으므로 Union을 모두 사용하여 서버가 필요하지 않습니다. 쿼리에서 두 테이블에 액세스하려는 다른 시간이 있습니다.
그런 다음보기를 사용하여 쿼리를 작성하십시오.
코드보기는 다음과 같습니다 (다른 목적으로 다른 필드를 원할 수도 있습니다.
Create view customerOrders
AS
SELECT customer.id as CustomerID, customer.name, p_orders.id as OrderID, p_items.price as price
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
union all
SELECT customer.id, customer.name, h_orders.id as id, H_items.price
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
그러면 쿼리 요청은 (이 중 어느 것도 조정이 필요하지 않을 수 있음)와 같은 것입니다.
SELECT CustomerID, customer.name, count(DISTINCT OrderID) AS num_orders,
sum(price) AS total_money
FROM customerOrders
GROUP BY CustomerID, customer.name
ORDER BY CustomerID
내가 아는 한 SQL Server는 자동으로 복제를 제거해야합니다. Union을 사용하면 모두 복제물이 포함됩니다. SQL Server는 기본 키를 복제품을 해결하는 수단으로 사용한다고 생각합니다. 이 테이블의 기본 키는 동일한 데이터 유형으로 구성되며 P 테이블의 ID 1도 H 테이블의 ID 1입니까?
당신이보고있는 일을하는 가장 쉬운 방법은보기 ( "a_orders"및 "a_items")를 만드는 것입니다. 보기는 다음과 같이 정의됩니다.
SELECT * FROM p_orders
UNION
SELECT * FROM h_orders
a_orders에서 행을 h_orders에 삽입 할 때 행을 삭제하면 (주어진 순서가 두 테이블에 있지 않음) Union 대신 Union을 사용하는 것이 훨씬 더 효율적입니다.
감사에 대한 모든 대답니다.
모두 보기 방식'과'부질의 방법에 의해'지미 R.Houts 완벽하게 작동하고,어쩌면 전망은 단지 사용하기 더 편리..고 그들을 모두 취해야 한다 같은 시간(또는지?)
그래서 나는 답변으로 표시 첫 번째 중 하나에 대한 전망이다.
어쨌든,수있는 경우,당신 요청할 수 있습니다면 구조와 인덱스가 사용되는 좋은 또는 최적화할 수 있습?