SQL一对多关系,重复/结果作为唯一行返回

时间:2018-12-11 21:57:15

标签: sql sql-server database one-to-many

我有一个数据库,某些表具有一对多关系。如何消除结果以其唯一的行形式返回?

例如,我有一个计划表,一个计划可以有很多资金需求。当我执行内部联接时,我得到的结果是,但似乎行正在重复以从资金表中输出唯一值。

Results

从结果来看,应该是这样

第3、4、5行应一列,列出结果以及所需的资金

Description | Acad_priority_1 | Acad_priority_2 | beginning_fiscal_year |
Develop...  |  false          | true            | 2018/2019             |
                                                | 2018/2019             |
                                                | 2019/2020

能否请您指导我正确的方向,或者告诉我应该如何构造SQL以实现这一目标?

SQL:

    SELECT plan_master.plan_id,
       plan_master.date_submitted,
       plan_master.filename,
       initiative_master.plan_id,
       initiative_master.NAME,
       initiative_master.acad_priority_1,
       funding.initiative_id,
       funding.beginning_fiscal_year
FROM   plan_master
       JOIN initiative_master
               ON plan_master.plan_id = initiative_master.plan_id
       JOIN funding
               ON initiative_master.initiative_id = funding.initiative_id  
ORDER BY Filename




|plan_id|date_submitted|filename|plan_id|NAME|acad_priority_1|initiative_id|begginning_fiscal_year|
|16F44FFE-5434-4E52-9D9A-F45C0A49D8E2|2018-12-03|1.txt|16F44FFE-5434-4E52-9D9A-F45C0A49D8E2|Space Utilization framework|false|8CCE0311-0E3C-467D-B675-04817A473056|2018/2019
|16F44FFE-5434-4E52-9D9A-F45C0A49D8E2|2018-12-03|1.txt|16F44FFE-5434-4E52-9D9A-F45C0A49D8E2|Space Utilization framework|false|8CCE0311-0E3C-467D-B675-04817A473056|2019/2020
|16F44FFE-5434-4E52-9D9A-F45C0A49D8E2|2018-12-03|1.txt|16F44FFE-5434-4E52-9D9A-F45C0A49D8E2|Space Utilization framework|false|8CCE0311-0E3C-467D-B675-04817A473056|2020/2021

2 个答案:

答案 0 :(得分:0)

简单联接将返回笛卡尔乘积。如果一个表有2行,而另一个表有3行,那么将有6行数据。需要对数据做不同的处理。您可以这样做:

SELECT plan.date_submitted,
   plan.filename,
   plan.department,
   plan.last_name,
   plan.first_name,
   plan.email,
   plan.mission_statement,
   plan.vision_statement,
   plan.goals_objectives,
   initiative.Name, 
   initiative.description,
   initiative.acad_priority_1,
   initiative.acad_priority_2,
   initiative.acad_priority_3,
   initiative.acad_priority_4,
   initiative.acad_priority_5,
   initiative.acad_priority_6
FROM plan_master as plan 
inner join (select distinct init.plan_id, init.NAME,
   init.description,
   init.acad_priority_1,
   init.acad_priority_2,
   init.acad_priority_3,
   init.acad_priority_4,
   init.acad_priority_5,
   init.acad_priority_6,
   init.operational_sustainability,
   init.people_plan,
   funding.beginning_fiscal_year from initiative_master as init
   join funding on funding.initiative_id = init.initiative_id ) as initiative  
    ON plan.plan_id = initiative.plan_id
ORDER BY Filename

答案 1 :(得分:0)

除非您要用逗号(或另一个分隔符)将它们连接起来,或者要编写一个函数来将值显示为范围,例如2018-2020,否则不能将两个会计年度开始的值合并为一行。但是,您可以使用distinct或使用下面提到的over / partition by子句来摆脱第四条记录。

如果您不介意,可以运行以下查询并提供结果以帮助我识别重复问题吗?

SELECT plan_master.plan_id,
       plan_master.date_submitted,
       plan_master.filename,
       plan_master.department,
       plan_master.last_name,
       plan_master.first_name,
       plan_master.email,
       plan_master.mission_statement,
       plan_master.vision_statement,
       plan_master.goals_objectives,
       initiative_master.plan_id,
       initiative_master.NAME,
       initiative_master.description,
       initiative_master.acad_priority_1,
       initiative_master.acad_priority_2,
       initiative_master.acad_priority_3,
       initiative_master.acad_priority_4,
       initiative_master.acad_priority_5,
       initiative_master.acad_priority_6,
       initiative_master.operational_sustainability,
       initiative_master.people_plan,
       funding.initiative_id,
       funding.beginning_fiscal_year
FROM   plan_master
       JOIN initiative_master
               ON plan_master.plan_id = initiative_master.plan_id
       JOIN funding
               ON initiative_master.initiative_id = funding.initiative_id  
ORDER BY Filename

一旦找到原因,则可以使用更好的join子句(多种条件),添加where子句或使用OVER clause in conjunction with the PARTITION BY clause来基于ROW_NUMBER()过滤数据。