1

场景很简单。我有 4 个表,A 表、B 表、C1 表和 C2 表。A 是根级表,B 引用 A,C1 和 C2 引用 B。但是每个 B.ID 只能被 C1 或 C2 引用,不能同时被两者引用。结果被导出到 .CSV 文件,然后用于各种目的,这里的问题与可读性有关,以及更容易管理外部软件中的信息。

我编写了一个查询,返回所有 4 个表中的所有数据,保持关系完整,按 A、B、C1 和 C2 排序。

SELECT A.*, B.*, C1.*, C2.*
FROM A
JOIN B 
LEFT JOIN C1
LEFT JOIN C2
ORDER BY A.ID, B.ID, etc.

得到了这个:

A.ID | B.ID | C1.ID | C2.ID
    1|     1|      1|  NULL
    1|     1|      2|  NULL
    1|     2|      1|  NULL
    1|     2|      2|  NULL
    1|     2|      3|  NULL
    2|     1|   NULL|     1
    2|     1|   NULL|     2
....

现在,这里的问题是:如何只为每个连接返回第一个不同的行,以便结果集不会被冗余数据阻塞。基本上,上面的结果应该产生这样的结果:

A.ID | B.ID | C1.ID | C2.ID
    1|     1|      1|  NULL
     |      |      2|  NULL
     |     2|      1|  NULL
     |      |      2|  NULL
     |      |      3|  NULL
    2|     1|   NULL|     1
     |      |   NULL|     2
....

我可以通过使每个连接成为子查询并按等级对结果进行分区来做到这一点,或者创建一个临时表并使用所需的逻辑猛击结果,但由于这将在控制台应用程序中使用,我想尽可能保持解决方案干净、简单和优化。

有任何想法吗?

4

1 回答 1

4

这是报告/格式化,而不是数据,所以它应该由应用程序处理,而不是 SQL。

也就是说,这将产生接近您要求的东西

select 
    case arn when 1 then convert(varchar(10),aid) else '' end as aid,
    case brn when 1 then convert(varchar(10),bid) else '' end as bid,
    case crn when 1 then convert(varchar(10),c1id) else '' end as c1id,
    c2id        
from
(    
           select a.id aid, b.id bid, c1.id c1id, c2.id c2id,
    ROW_NUMBER() over(partition by a.id order by a.id,b.id,c1.id,c2.id) arn,
    ROW_NUMBER() over(partition by a.id,b.id order by a.id,b.id,c1.id,c2.id) brn,
    ROW_NUMBER() over(partition by a.id,b.id,c1.id order by a.id,b.id,c1.id,c2.id) crn
           FROM A 
           JOIN B  
           LEFT JOIN C1 
           LEFT JOIN C2 

) v
于 2012-09-07T10:27:09.500 回答