这个postgres sql查询中的交叉表的目的是什么?

时间:2016-04-16 03:05:29

标签: postgresql

我一般都是SQL的新手......这个查询中交叉表的目的是什么?它是如何工作的?为什么需要它? (这是使用订阅模型的Rails 4.2应用程序,但我对SQL感兴趣。)

      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

1 个答案:

答案 0 :(得分:0)

它是一个内置的postgres函数,它将给定行的所有值分组并将它们转移到同一行。在如上所述的连接查询中,您最终可以使用

row1 val1
row1 val2
row1 val3
row2 val1
row2 val2
row2 val3

使用交叉表,您可以将其格式化为:

row1 val1 val2 val3
row2 val1 val2 val3

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