SQL复杂的透视查询

时间:2014-04-03 09:03:49

标签: sql pivot

我有3张桌子:

公司,联系人和公司_联系

表Company_Contact保存company_id和contact_id之间的连接,每个联系人也可以与sevral公司相关。

每个公司都有不同数量的联系人,我需要一个查询,它会以这种形式为我提供数据:

company_name  contact_1   contact_2   contact_3   contact_4   contact_5
----------    ---------   ----------  ----------  ---------- -----------
company1       aaa         ddd         ggg        iii         kkk
company2       bbb         eee         hhh        jjj         lll
company3       ccc         fff         NULL        NULL       NULL

我不确定每个公司是否有5个联系人,但要求是为每个公司提供前5个联系人。

我不知道如何使用枢轴(如果枢轴是真正的答案)。

如何创建查询来实现此目标?

2 个答案:

答案 0 :(得分:0)

假设这是TSQL,当你提到pivot时,你可以使用cte的组合来生成行号,然后使用数据透视。

with cte1 as (
    select com.company_id as [Company Id],
           row_number() over (partition by com.company_id order by con.contact_id) as row, 
           [Contact Name] from contacts con
           inner join company_contacts com on com.contact_id=con.contact_id
),
cte2 as (
   select * from cte1 where row < 6
)

select co.[Company Name], 
       c.[1] as contact_1,
       c.[2] as contact_2,
       c.[3] as contact_3,
       c.[4] as contact_4,
       c.[5] as contact_5

from Companies co 
left outer join
(select * 
 from cte2
 pivot (min([Contact Name]) for row in ([1],[2],[3],[4],[5])) x
) c on c.[company id] = co.company_id

答案 1 :(得分:0)

这是我的解决方案:

/** Part 1 : Ctreate Table of test */
WITH Temp AS(
SELECT 'Company1' CompanyName, 'Contact A' ContactName, 80 Amount UNION ALL
SELECT 'Company1' CompanyName, 'Contact B' ContactName, 11040 Amount UNION ALL
SELECT 'Company1' CompanyName, 'Contact C' ContactName, 160 Amount UNION ALL
SELECT 'Company1' CompanyName, 'Contact D' ContactName, 10 Amount UNION ALL
SELECT 'Company1' CompanyName, 'Contact E' ContactName, 100 Amount UNION ALL
SELECT 'Company1' CompanyName, 'Contact F' ContactName, 12100 Amount UNION ALL
SELECT 'Company1' CompanyName, 'Contact G' ContactName, 16800 Amount UNION ALL
SELECT 'Company1' CompanyName, 'Contact H' ContactName, 120000 Amount UNION ALL

SELECT 'Company2' CompanyName, 'Contact I' ContactName, 100 Amount UNION ALL
SELECT 'Company2' CompanyName, 'Contact J' ContactName, 100 Amount UNION ALL
SELECT 'Company2' CompanyName, 'Contact K' ContactName, 300 Amount UNION ALL
SELECT 'Company2' CompanyName, 'Contact L' ContactName, 400 Amount UNION ALL
SELECT 'Company2' CompanyName, 'Contact M' ContactName, 500 Amount UNION ALL
SELECT 'Company2' CompanyName, 'Contact N' ContactName, 1100 Amount UNION ALL
SELECT 'Company2' CompanyName, 'Contact O' ContactName, 1200 Amount UNION ALL

SELECT 'Company3' CompanyName, 'Contact P' ContactName, 8 Amount UNION ALL
SELECT 'Company3' CompanyName, 'Contact Q' ContactName, 10 Amount UNION ALL
SELECT 'Company3' CompanyName, 'Contact R' ContactName, 100 Amount UNION ALL
SELECT 'Company3' CompanyName, 'Contact S' ContactName, 700 Amount UNION ALL
SELECT 'Company3' CompanyName, 'Contact T' ContactName, 600 Amount UNION ALL
SELECT 'Company3' CompanyName, 'Contact B' ContactName, 100 Amount UNION ALL
SELECT 'Company3' CompanyName, 'Contact C' ContactName, 150 Amount UNION ALL
SELECT 'Company3' CompanyName, 'Contact D' ContactName, 1300 Amount UNION ALL
SELECT 'Company3' CompanyName, 'Contact J' ContactName, 12000 Amount
)

/*Part 2 : Create the SQL Statement*/

SELECT
         CompanyName
        ,contact_1
        ,contact_2
        ,contact_3
        ,contact_4
        ,contact_5
FROM
    (SELECT
             CompanyName
            ,ContactName
            ,CASE Ordre
                WHEN 1 THEN 'contact_1'
                WHEN 2 THEN 'contact_2'
                WHEN 3 THEN 'contact_3'
                WHEN 4 THEN 'contact_4'
                WHEN 5 THEN 'contact_5'
             END Column_pivot
    FROM 
        (SELECT
                *
                ,ROW_NUMBER() OVER (PARTITION BY CompanyName ORDER BY     Amount     DESC) Ordre from Temp
        ) AS T
    WHERE
        Ordre <= 5 ) AS TT
PIVOT (MAX(ContactName)
    FOR Column_pivot in( contact_1, contact_2, contact_3, contact_4, contact_5 )) as pvt

我希望它能帮到你:) 祝你好运