2016-04-16 9 views
0

Ich bin neu in SQL im Allgemeinen ... Was ist der Zweck von Kreuztabelle in dieser Abfrage? Wie funktioniert es? Warum wird es benötigt? (Dies ist übrigens von einer Rails 4.2 App mit einem Subskriptionsmodell, aber ich bin an der SQL interessiert).Was ist der Zweck der Kreuztabelle in dieser Postgres-SQL-Abfrage?

 Subscription.select(<<-SQL.sub(/\n$/, '') 
subscriptions.braintree_account_id as braintree_account_id, \ 
subscriptions.braintree_subscription_id as braintree_subscription_id, \ 
format('%s %s', addresses.first_name, addresses.last_name) as billing_address_full_name, \ 
users.email as email, \ 
addresses.line_1 as billing_address_line_1, \ 
addresses.city as billing_address_city, \ 
addresses.state as billing_address_state, \ 
addresses.zip as billing_address_zip_code, \ 
addresses.country as billing_address_country, \ 
CASE WHEN subscriptions.shirt_size IS NULL THEN '' ELSE regexp_replace(subscriptions.shirt_size, '\s', '') END as shirt_size, \ 
CASE WHEN main_handbag IS NULL THEN '' ELSE main_handbag END, \ 
CASE WHEN european_handbag IS NULL THEN '' ELSE european_handbag END, \ 
CASE WHEN india_handbag IS NULL THEN '' ELSE india_handbag END, \ 
CASE WHEN billing_methods.option IS NULL THEN 'standard' ELSE billing_methods.option END as billing_option, \ 
plans.name as plan_name, \ 
products.sku as sku, \ 
to_char(subscriptions.created_at, 'MM/DD/YYYY HH24:MM:SS') as subscription_created_at, \ 
to_char(subscriptions.next_assessment_at, 'MM/DD/YYYY HH24:MM:SS') as subscription_next_assessment_at, \ 
subscriptions.subscription_status as subscription_status, \ 
'#{ Handbag.current }'::text as handbag 
SQL 
    ).joins(:billing_address). 
     joins('LEFT OUTER JOIN billing_methods ON billing_methods.subscription_id = subscriptions.id'). 
     joins('LEFT OUTER JOIN plans ON subscriptions.plan_id = plans.id'). 
     joins('LEFT OUTER JOIN users ON subscriptions.user_id = users.id'). 
     joins('LEFT OUTER JOIN products ON plans.product_id = products.id'). 
     joins("LEFT OUTER JOIN (SELECT * 
       FROM crosstab('SELECT subscriptions.id, handbag_types.id, handbag_values.presentation 
       FROM subscriptions 
       LEFT JOIN subscription_variants ON subscriptions.id=subscription_variants.subscription_id 
       LEFT JOIN variants ON subscription_variants.variant_id=variants.id 
       LEFT JOIN handbag_value_variants ON variants.id=handbag_value_variants.variant_id 
       LEFT JOIN handbag_values ON handbag_value_variants.handbag_value_id=handbag_values.id 
       LEFT JOIN handbag_types ON handbag_values.handbag_type_id=handbag_types.id ORDER BY 1,2', 
        'select handbag_types.id FROM handbag_types ORDER BY handbag_types.id ASC') 
       AS (subscription_id int, main_handbag VARCHAR, european_handbag VARCHAR, india_handbag VARCHAR)) subscription_variant_view 
     ON subscriptions.id=subscription_variant_view.subscription_id"). 
     where(subscription_status: 'active') 
    end 

Antwort

0

Es ist ein in postgres eingebaute Funktion, die Gruppen alle Werte für eine gegebene Zeile und sich auf die gleiche Reihe verschwenkt. In einer Join-Abfrage wie die oben Sie mit

könnte am Ende
row1 val1 
row1 val2 
row1 val3 
row2 val1 
row2 val2 
row2 val3 

Mit Kreuztabellen-, könnten Sie das in formatieren:

row1 val1 val2 val3 
row2 val1 val2 val3 

Dokumentation: http://www.postgresql.org/docs/9.2/static/tablefunc.html