连接表没有重复

时间:2015-10-07 05:32:18

标签: sql sql-server

我有3个SQL表格如下:

表1

ItemId Name
----------
A      aa    
B      bb

表2

ItemId Category
----------
A      1
A      2
A      3
B      1

表3

ItemId  Dep
----------
A       D1
B       D2
B       D3

我需要结果

ItemId Name Category Dep
------------------------
A      aa   1        D1
            2
            3   
B      bb   1        D2
                     D3

有没有办法在没有循环表的情况下得到这个结果?

4 个答案:

答案 0 :(得分:1)

您可以先JOIN ItemId上的表格,然后使用ROW_NUMBERRANK进行格式化。

我建议你在客户端进行显示格式

SQL Fiddle

WITH CTE AS(
    SELECT
        t1.ItemId, t1.Name, t2.Category, t3.Dep,
        Rn_Cat  = ROW_NUMBER() OVER(PARTITION BY t1.ItemId, t1.Name ORDER BY t2.Category),
        Rn_Dep  = ROW_NUMBER() OVER(PARTITION BY t1.ItemId, t1.Name ORDER BY t3.Dep),
        Rnk_Cat = RANK() OVER(PARTITION BY t1.ItemId, t1.Name ORDER BY t2.Category),
        Rnk_Dep = RANK() OVER(PARTITION BY t1.ItemId, t1.Name ORDER BY t3.Dep)
    FROM Table1 t1
    LEFT JOIN Table2 t2
        ON t2.ItemId = t1.ItemId
    LEFT JOIN Table3 t3
        ON t3.ItemId = t1.ItemId
)
SELECT
    ItemId = CASE WHEN Rn_Cat = 1 THEN ItemId ELSE '' END,
    Name = CASE WHEN Rn_Cat = 1 THEN Name ELSE '' END,
    Category = CASE WHEN Rn_Cat = Rnk_Cat THEN CONVERT(VARCHAR(10), Category) ELSE '' END,
    Dep = CASE WHEN Rn_Dep = Rnk_Dep THEN CONVERT(VARCHAR(10), Dep) ELSE '' END
FROM CTE

答案 1 :(得分:0)

可能正在使用UNION

Fiddle Here

WITH CTE AS(
    SELECT
    t2.ItemId,t1.Name,t2.Category,t3.Dep,
  Rank() over(Partition by t1.ItemId,t1.Name order by t2.Category,t3.Dep) as rn
  from 
  Table1 t1 join Table2 t2 on t1.ItemId=t2.ItemId
  join Table3 t3 on t1.ItemId=t3.ItemId
)
SELECT
ItemId,Name,Category,Dep,Rn
FROM CTE where rn=1
union 
SELECT
'','',Category,Dep,Rn
FROM CTE where rn>1

答案 2 :(得分:0)

这可能会奏效:

;with cte_t1 as
(
select  'A' as ItemId, 'aa' as Name
union
select  'B' as ItemId, 'bb' as Name
),
cte_t2 as
(
select 'A' AS ItemId, 1 as Category
union
select 'A' AS ItemId, 2 as Category
union
select 'A' AS ItemId, 3 as Category
union
select 'B' AS ItemId, 1 as Category
),
cte_t3 as
(
select 'A' AS ItemId, 'D1' as Dep
union
select 'B' AS ItemId, 'D2' as Dep
union
select 'B' AS ItemId, 'D3' as Dep
),
cte_t4 as
(
SELECT T1.ItemId, t1.Name, T2.Category, T3.Dep, ROW_NUMBER() over(order by T1.ItemId, T2.Category) RowNumber
FROM cte_t1 t1 inner join cte_t2 t2
    on t1.ItemId = t2.ItemId 
        inner join cte_t3 t3
            on t1.ItemId = t3.ItemId
            and t2.ItemId = t3.ItemId
)
select  
case when a.ItemId = b.ItemId then '' else a.ItemId end as ItemId, 
case when a.Name = b.Name then '' else a.Name end as Name, 
case when a.Category = b.Category then '' else cast(a.Category as varchar(100)) end as Category, 
case when a.Dep = b.Dep then '' else a.Dep end as Dep
from cte_t4  a
    left join cte_t4 b
        on a.RowNumber-1= b.RowNumber

答案 3 :(得分:0)

使用此代码 -

SELECT table1.ItemID,
       table1.Name,
       table2.Category,
       table3.Dep
FROM table1, table2, table3
WHERE table1.ItemID = table2.ItemID AND table1.ItemID = table3.ItemID;

产生此输出 -

+--------+------+----------+-----+
| ItemID | Name | Category | Dep |
+--------+------+----------+-----+
| A      | aa   | 1        | D1  |
| A      | aa   | 2        | D1  |
| A      | aa   | 3        | D1  |
| B      | bb   | 1        | D2  |
| B      | bb   | 1        | D3  |
+--------+------+----------+-----+

这就是您所追求的,或者您是否希望每次重复显示一个空格?