2014-08-29 3 views
2

두 개의 테이블이 있습니다. 송장 번호, 부품 번호 및 수량을 포함하는 판매 테이블과 번들 테이블, 번들 ID 포함, 부품 번호 및 수량. 예컨대 :추가 조건이있는 SQL 관계 구분

판매 :

Invoice_No | Part_No | QTY 
----------------------------- 
1   |aaa  |1 
1   |bbb  |2 
1   |ccc  |1 
2   |aaa  |1 
2   |ccc  |1 
2   |ddd  |2 
3   |aaa  |1 
3   |bbb  |1 
3   |ccc  |1 

번들 :

BID | Part_No | QTY 
------------------- 
1 |aaa  |1 
1 |bbb  |2 
1 |ccc  |1 
2 |aaa  |1 
2 |ccc  |1 
2 |ddd  |1 

나는 적어도 필요한 수량과 주어진 번들의 부품이 모두 포함 된 송장을 확인하는 쿼리를합니다. https://www.simple-talk.com/sql/t-sql-programming/divided-we-stand-the-sql-of-relational-division/

SELECT S.Invoice_No, 1 as Bundle From Sales as S 
INNER JOIN (SELECT BID, Part_No, QTY FROM Bundles WHERE BID=1) as B 
ON S.Part_No=B.Part_No 
GROUP BY S.Invoice_No 
HAVING COUNT(S.Part_No)=(SELECT count(Part_No) FROM Bundles WHERE BID=1) 

그러나 :

즉 송장 001이 번들을 포함 1 및 송장 002 내가 거기 여기에 예를보고하는 방식의 일부를 얻을 수있었습니다 2

번들을 포함 이 쿼리는 인보이스 3을 번들 1로 잘못 인식합니다. 각 번들마다 별도의 쿼리를 작성하지 않아도되므로 향후 번들을 추가하는 데 많은 시간이 소요됩니다.

확장 프로그램에서 둘 이상의 번들을 포함하는 인보이스 (예 : 인보이스에 2 개의 번들 1 또는 1 개의 번들 1 및 1 번들 2 포함)을 식별 할 수 있기를 바랍니다.

이 데이터는 MS ACCESS를 사용하고 있습니다.

+0

쿼리에 "BID"라는 필드가 사용되지만 번들 테이블에 해당 필드가 없습니다. "ID"라는 필드가 있습니다. 어느 것이 옳은가요? –

+0

송장 001에 번들 1이 들어 있음을 어떻게 알 수 있습니까? BundleId는 InvoiceId와 관련이 있습니까? 번들 테이블이 송장 테이블의 정보를 복제하거나이 두 객체를 조인하는 다른 테이블이 있습니다 (그렇지 않은 경우) –

+0

인보이스가 특정 번들과 관련되어 있는지 식별하는 실제 방법을 추측합니다 번들에 인보이스의 모든 일치하는 part_no 값이 포함되어 있습니까? 현재 쿼리가 수행하는 작업과는 거리가 멀기는하지만. –

답변

0

(내가 잘못 일부 필드 이름이없는 경우) 다음은 설정하면 데이터를 기반으로, 어떻게해야

SELECT S.Invoice_No, B.BID, count(S.part_no) 
FROM SALES as S 
INNER JOIN Bundle as B ON S.Part_No = B.Part_No AND S.qty >= B.qty 
GROUP BY S.INVOICE_no, B.BID 
HAVING COUNT(S.Part_No) >= (SELECT count(B2.Part_No) 
          FROM Bundle B2 
          WHERE B2.BID = B.BID) 

SQL Fiddle

더 이상의 기대 없을 때 위의 간단한 경우에 작동합니다 판매 당 번들. 추가 품목이 송장 1 (예 : 단일 'ddd')에 추가 된 경우 번들 1 & 번들 2를 충족하는 데 충분한 부품이 있다고 계산합니다. 다른 번들을 제외하지 않기 때문입니다.

예 :

INSERT INTO SALES VALUES (1, 'aaa', 1); -- satisfies Bundle 1 and Bundle 2 
INSERT INTO SALES VALUES (1, 'bbb', 2); -- satisfies Bundle 1 
INSERT INTO SALES VALUES (1, 'ccc', 1); -- satisfies Bundle 1 and Bundle 2 
INSERT INTO SALES VALUES (1, 'ddd', 1); -- satisfies Bundle 2 

그러나 진정으로 만족하는 BOTH 번들은 각각 'AAA'와 'CCC'의 2가 있어야 위해

. 이 세부 수준이 필요한 경우 추가 기준이 필요합니다. 그렇지 않다면, 필요 이상으로 복잡하게 만들지 마십시오. 추가 행이있는 SQL Fiddle입니다.

+0

흠, 그렇지 않다. 꽤 일하지 않아. 해당 쿼리는 송장 1과 2에 대해 송장 1과 2에 대해 송장 2와 송장 3에 대해 2를 반환합니다. –

+0

다음 쿼리는 BID 1에 대해 작동하지만 이상하게 BID 2 SELECT S.Invoice_No에 대해서는 판매되지 않음 1은 Bundle From Sales로 S INPUT_No = B.Part_No 및 S.QTY> = B.QTY GROUP BY S.Invoice_No 으로 INNER JOIN (선택 BID, Part_No, BID = 1 번들에서 수량) HAVING COUNT (S.Part_No) = (SELECT count (Part_No) FROM 번들 WHERE BID = 1) –

+0

SQL Fiddle 또는 데이터 세트에 대해 시도 했습니까? –

1
-- the data 
CREATE TABLE sales 
     (seq SERIAL NOT NULL PRIMARY KEY 
     , invoice_no INTEGER NOT NULL 
     , part_no CHAR(3) NOT NULL 
     , qty INTEGER NOT NULL DEFAULT 0 
     ); 
INSERT INTO sales (invoice_no, part_no, qty) VALUES 
(1, 'aaa' ,1) ,(1, 'bbb' ,2) ,(1, 'ccc' ,1) 
,(2, 'aaa' ,1) ,(2, 'ccc' ,1) ,(2, 'ddd' ,2) 
,(3, 'aaa' ,1) ,(3, 'bbb' ,1) ,(3, 'ccc' ,1) 
     ; 

CREATE TABLE bundles 
     (seq SERIAL NOT NULL PRIMARY KEY 
     , bid INTEGER NOT NULL 
     , part_no CHAR(3) NOT NULL 
     , qty INTEGER NOT NULL DEFAULT 0 
     ); 

INSERT INTO bundles(bid, part_no, qty) VALUES 
(1, 'aaa' ,1) , (1, 'bbb' ,2) , (1, 'ccc' ,1) 
, (2, 'aaa' ,1) , (2, 'ccc' ,1) , (2, 'ddd' ,1) 
     ; 

SELECT * FROM sales; 
SELECT * FROM bundles; 


     -- find the orders 
SELECT * FROM sales sa 
WHERE EXISTS ( -- sales is part of some bundles 
       -- find all bundles containing the articles in these orders 
     SELECT * FROM bundles bu 
     WHERE bu.part_no = sa.part_no 
     AND NOT EXISTS (-- this bundle MUST contain ALL items from this order 
         -- ==>> bundle MUST NOT contain ANY item NOT in this order 
         -- (or in too low qty) 
       SELECT * 
       FROM bundles xb 
       WHERE xb.bid = bu.bid 
       AND NOT EXISTS (-- 
         SELECT * FROM sales xs 
         WHERE xs.part_no = xb.part_no 
         AND xs.invoice_no = sa.invoice_no 
         AND xs.qty >= xb.qty 
         ) 
       ) 
     ) 
     ;