2012-03-24 2 views
1

제품, 인보이스 및 클라이언트가 있습니다. 고객 송장에는 판매 가격에 세금이 부과되지 않는 제품이 있습니다. product_id =45, 가장 낮은 판매 가격 및 첫 번째 인보이스의 판매 가격에 대해 각 고객에 대해보고해야합니다.그룹화 된 행의 첫 번째 행에서 값을 얻으려면 어떻게해야합니까?

마지막 조건을 제외한 모든 것을 그룹화 할 수 있습니다. 나는 그것이 subselect으로 끝날 수 있다는 것을 알고 있지만, 나는 그것을 피하고 싶습니다.

간체 데이터베이스 구조 :

table clients 
-clent_id serial 

table products 
-product_id serial 
-name text 

table invoices 
-invoice_id serial 
-client_id int 

table invoices_rows 
-invoice_row_id serial 
-invoice_id int 
-product_id int 
-price double precision 
+0

현재 검색어가 어떻게 실패합니까? – bernie

답변

3

DISTINCT와 함께 사용 window functions (요청에 따라 부속없이) 가장 낮은 동시에 최초의 가격 얻을 :

SELECT DISTINCT ON (i.client_id) 
     i.client_id 
    , min(ir.price) OVER (PARTITION BY i.client_id) AS min_price 
    , first_value(ir.price) OVER (PARTITION BY i.client_id 
            ORDER BY ir.invoice_id) AS first_price 
FROM invoices_rows ir 
JOIN invoices i USING (client_id) 
WHERE ir.product_id = 45; 

이 (DISTINCT ON 적용 client_id) client_id 당 하나의 행을 가져옵니다. DISTINCT는 창 기능 후에 적용되며 GROUP BY은 이전에 적용됩니다.

"첫 번째 인보이스"는 "최저 invoice_id"으로 해석 될 수 있다고 가정합니다. 각 고객별로 "최저 판매 가격"이 필요합니까? 또는 제품의 전반적인 최저 가격입니까? 이제 'per client_id'로 변경되었습니다. 좀 더 가능성이 높습니다. 당신이 부속 또는 CTE 상관하지 않을 경우


이 아마 가장 잘 수행 할 것입니다 :

WITH x AS (
    SELECT i.client_id 
     , min(ir.price) AS min_price 
     , min(ir.invoice_id) AS invoice_id 
    FROM invoices_rows ir 
    JOIN invoices i USING (client_id) 
    WHERE ir.product_id = 45 
    ) 
SELECT x.*, ir.price AS first_price 
FROM x 
JOIN invoices_rows ir USING (invoice_id) 
0

내가 그건 당신이 sale_date에 대한 정보를 필요 맨 처음 송장에서 판매 가격을 생각하거나 귀하의 요청에 설명하지 않은 유효한 기준.

그 결과를 얻는 데는 여러 가지 방법이 있지만, 내가 선호하는 방법은 집계 함수에만 근거합니다. 다음 샘플에서는 postges을 사용하지만 다른 DB에서도 동일한 기능을 제공 할 수 있습니다.

postgres=# select * 
postgres-# from prices_products; 
product_name | customer_name | price | sell_date 
--------------+---------------+-------+------------ 
knife  | mark   | 100 | 2011-01-20 
book   | cris   | 20 | 2011-05-12 
book   | mark   | 25 | 2010-09-30 
book   | cris   | 30 | 2012-02-15 
(4 rows) 


postgres=# 
postgres=# select product_name, customer_name,m as maximum, arr[1] as first_date_val 
postgres-# from (
postgres(#    select product_name, customer_name, max(price) as m, array_agg(price order by sell_date) as arr 
postgres(#    from prices_products 
postgres(#    group by product_name, customer_name 
postgres(#  ) a; 
product_name | customer_name | maximum | first_date_val 
--------------+---------------+---------+---------------- 
book   | cris   |  30 |    20 
book   | mark   |  25 |    25 
knife  | mark   |  100 |   100 
(3 rows) 


postgres=# 
관련 문제