2017-02-02 1 views
0

PostgreSQL에 두 개의 테이블이 있습니다. 기부금이있는 테이블과 기능이있는 테이블. donation_id를 각 기능에 할당하려고하지만 donation_id의 일부는 기부 테이블에있는 용량에 따라 테이블의 여러 레코드에 할당해야합니다.PostgreSQL, 한 테이블의 여러 레코드를 다른 테이블의 단일 레코드에 할당하십시오.

예 : 누군가 10 명을 기부 한 다음 2 명마다 기부금 ID가 동일한 동일한 기부 테이블의 기부금 5 개 레코드에 기부금을 지정해야합니다.

기능이 이미 존재하며 모두 고유 한 값을 갖고 있기 때문에 업데이트 구문을 찾고 있습니다. 어떤 기능이 어떤 기부금에 할당되는지는 중요하지 않으며 수량 만 중요합니다.

기부 :

donation_id | ammount 
===================== 
001   | 10 
002   | 4 

특징 :

feature_id | donation_id | owned 
================================= 
001   | 000   | false 
002   | 000   | false 
003   | 000   | false 
004   | 000   | false 
005   | 000   | false 
006   | 000   | false 
007   | 000   | false 
008   | 000   | false 

출력 :

feature_id | donation_id | owned 
================================= 
001   | 001   | true 
002   | 001   | true 
003   | 001   | true 
004   | 001   | true 
005   | 001   | true 
006   | 002   | true 
007   | 002   | true 
008   | 000   | false 
+2

** ** [질문] ** 귀하의 질문을 추가하고 샘플 데이터와 예상되는 결과를 해당 데이터를 기반으로 추가하십시오. [** 포맷 된 텍스트 **] (http://stackoverflow.com/help/formatting)하시기 바랍니다. [스크린 샷 없음] (http://meta.stackoverflow.com/questions/285551/why-may-i-not -upload-images-of-code-on-so-ask-a-question/285557 # 285557) –

+0

기부금이 2의 배수가 아닌 경우 어떻게 될까요? 기부금을받을 수있는 기능이 충분하지 않다면 어떻게해야합니까? –

+0

기부금이 2의 배수가 아닌 경우 반올림해야합니다. 충분한 기능이있을 것입니다. – Titsjmen

답변

0

당신은 재생하는 Common Table Expression (또는 두 개의 임시 테이블, 또는 하위 쿼리 및 이중화)를 사용할 수 있습니다 몇 가지 트릭을 통해 :

  1. generate_series이있는 CROSS JOIN (데카르트 제품)을 사용하면 반복되는 행을 얻을 수 있습니다. [row_number() 열을 추가하여 구별 할 수 있습니다.]
  2. 표현식을 사용하여 feature_idLIMIT을 사용하여 특정 수의 기능을 선택할 수 있습니다. 다시 말하지만 row_number() 열을 추가하여 구별 할 수 있습니다. 내가 feature_id가 있다고 가정 한

    • :

      -- Get a (virtual) table with "donation_id" repeated as many times 
      -- as (amount/2). Trick: use a CROSS JOIN with generate_series 
      WITH new_features AS 
      (
          SELECT 
           donation_id, row_number() over() AS rn 
          FROM 
           donations 
           CROSS JOIN generate_series(1, amount/2) AS g(i) 
      ), 
      -- Right now we know how many rows we want to UPDATE. 
      -- The next SELECT chooses them. Trick: computed LIMIT 
      to_update AS 
      (
          SELECT 
           feature_id, row_number() over() AS rn 
          FROM 
           features 
          WHERE 
           NOT owned 
          ORDER BY 
           feature_id -- This is arbitrary, it could even not be sorted. 
          LIMIT 
           (SELECT count(*) FROM new_features) 
      ) 
      -- ... and finally 
      UPDATE 
          features 
      SET 
          donation_id = new_features.donation_id, owned = true 
      FROM 
          to_update 
          JOIN new_features USING(rn) 
      WHERE 
          features.feature_id = to_update.feature_id 
      RETURNING 
          features.feature_id, features.donation_id, features.owned ; 
      

      당신은 RexTester


      주에서 그것을 확인할 수 있습니다

그래서, 다음 코드는 트릭을 수행 기본 키 (또는 대체 키 : 고유하고 null이 아님)). 이것이 사실이 아니라면 적절한 PK가 필요합니다.

  • owned 열을 사용하는 대신 이 not owned을 의미 할 때 donation_id 일 수 있습니다. 그러면 업데이트 할 필요가없는 열을 절약 할 수 있습니다.
  • 관련 문제