【问题标题】:Sql Server query not giving correct resultsSql Server 查询没有给出正确的结果
【发布时间】:2019-07-07 05:08:29
【问题描述】:

我在 Sql server 中有 3 个表。以下是表的结构。

员工表将包含员工列表。项目表将有项目列表。映射表将具有员工和项目之间的映射以及每周结束的小时数。映射表不会包含所有员工和项目的所有周末的映射。 我需要加入 3 个表格并在一周内获得所有员工针对特定项目的结果。如果某个特定员工在这个周末没有工作时间,则应提供员工详细信息,但工作时间应为 0。

我有以下查询,但它只显示映射表中具有 weekEnding 值的员工。

    SELECT RT.EMP_ID,RT.EMP_NAME, RT.EMP_EMAIL_ID, RPM.WEEK_ENDING, RPM.RSC_HOURS_LOGGED
 FROM vl.rsrc_prjct_hrs_mapping RPM  right outer Join vl.resource  RT ON RT.EMP_ID = RPM.EMP_ID 
 JOIN 
 vl.project PT ON PT.PROJECT_ID=RPM.PROJECT_ID WHERE PT.PROJECT_IRM='TMPT-4854' AND
  PT.PROJECT_DESC='33801-Urgent Care EnhancementEPDS V2' AND 
  RPM.WEEK_ENDING BETWEEN '2018-07-07' AND '2018-08-07';

但我想要所有的员工,但是周末应该到了,小时数应该是 0。

我也尝试使用以下查询:

select RT.EMP_ID,RT.EMP_NAME, RT.EMP_EMAIL_ID,tt.week_ending,tt.RSC_HOURS_LOGGED from vl.resource  RT left outer join (select RPM.EMP_ID,RPM.WEEK_ENDING, RPM.RSC_HOURS_LOGGED from vl.rsrc_prjct_hrs_mapping RPM join vl.project PT ON PT.PROJECT_ID=RPM.PROJECT_ID WHERE PT.PROJECT_IRM='TMPT-4854' AND PT.PROJECT_DESC='33801-Urgent Care EnhancementEPDS V2' AND RPM.WEEK_ENDING BETWEEN '2018-07-07' AND '2018-07-07') tt on RT.EMP_ID = tt.EMP_ID;

但这给出了员工表中的所有员工,但我只想要特定项目的员工。

【问题讨论】:

  • 将 RPM 条件从 WHERE 移至 ON。
  • @jarlh 你能修改查询并给我吗?我听不懂你在说什么
  • 请阅读minimal reproducible example并采取行动。请使用文本而不是图像/链接作为文本,包括表格和 ERD。展示你能做的部分。了解什么外连接返回:行内连接加上由空值扩展的不匹配的左表行。 PS 这是一个常见问题解答,通过谷歌搜索您的问题/问题/目标的清晰、简洁、准确的陈述很容易找到。

标签: sql sql-server join


【解决方案1】:

RIGHT OUTER JOINJOIN 隐式转换为 INNER JOIN 因此右外连接在这里没有用。更改连接顺序或同时进行外部连接

您还需要将RPM.WEEK_ENDING BETWEEN '2018-07-07' AND '2018-08-07' 移动到Right outer joinON 子句

SELECT 
   RT.EMP_ID,
   RT.EMP_NAME, 
   RT.EMP_EMAIL_ID, 
   RPM.WEEK_ENDING, 
   RPM.RSC_HOURS_LOGGED
FROM vl.rsrc_prjct_hrs_mapping RPM  
right outer Join vl.resource  RT 
  ON RT.EMP_ID = RPM.EMP_ID and
  RPM.WEEK_ENDING BETWEEN '2018-07-07' AND '2018-08-07'
... OUTER JOIN vl.project PT 
  ON PT.PROJECT_ID=RPM.PROJECT_ID  and 
     PT.PROJECT_DESC='33801-Urgent Care EnhancementEPDS V2' AND
     PT.PROJECT_IRM='TMPT-4854'

【讨论】:

  • 我试过这个查询:SELECT RT.EMP_ID, RT.EMP_NAME, RT.EMP_EMAIL_ID, RPM.WEEK_ENDING, RPM.RSC_HOURS_LOGGED FROM vl.rsrc_prjct_hrs_mapping RPM 右外加入 vl.resource RT ON RT.EMP_ID = RPM.EMP_ID 全外部 JOIN vl.project PT ON PT.PROJECT_ID=RPM.PROJECT_ID 和 PT.PROJECT_DESC='33801-紧急护理增强EPDS V2' AND PT.PROJECT_IRM='TMPT-4854' 其中 RPM.WEEK_ENDING BETWEEN '2018-07 -07' 和 '2018-07-07';但结果将在本周结束所有项目。我只想要一个特定的项目
  • 能否提供示例数据和预期输出:)
【解决方案2】:

我不建议使用right join。这只是令人困惑。使用let join -- 保留第一个表中的所有行,并保留后续表中的匹配行。

所以,如果你想保留所有员工,那就从那个表开始:

SELECT RT.EMP_ID, RT.EMP_NAME, RT.EMP_EMAIL_ID, RPM.WEEK_ENDING, RPM.RSC_HOURS_LOGGED
FROM vl.resource RT LEFT JOIN
     vl.rsrc_prjct_hrs_mapping RPM 
     ON RT.EMP_ID = RPM.EMP_ID AND
        RPM.WEEK_ENDING BETWEEN '2018-07-07' AND '2018-08-07' LEFT JOIN 
     vl.project PT
     ON PT.PROJECT_ID = RPM.PROJECT_ID AND
        PT.PROJECT_IRM = 'TMPT-4854' AND
        PT.PROJECT_DESC = '33801-Urgent Care EnhancementEPDS V2' ;

对项目的过滤进入ON子句。

如果您只希望曾经参与过该项目的人,那么您需要额外的过滤。我认为这会做你想要的:

SELECT RT.EMP_ID, RT.EMP_NAME, RT.EMP_EMAIL_ID, RPM.WEEK_ENDING, RPM.RSC_HOURS_LOGGED
FROM vl.resource RT LEFT JOIN
     vl.rsrc_prjct_hrs_mapping RPM 
     ON RT.EMP_ID = RPM.EMP_ID AND
        RPM.WEEK_ENDING BETWEEN '2018-07-07' AND '2018-08-07' LEFT JOIN 
     vl.project PT
     ON PT.PROJECT_ID = RPM.PROJECT_ID AND
        PT.PROJECT_IRM = 'TMPT-4854' AND
        PT.PROJECT_DESC = '33801-Urgent Care EnhancementEPDS V2'
WHERE EXISTS (SELECT 1
              FROM vl.rsrc_prjct_hrs_mapping RPM2 JOIN
                   vl.project PT2
                   ON PT2.PROJECT_ID = RPM2.PROJECT_ID AND
                      PT2.PROJECT_IRM = 'TMPT-4854' AND
                      PT2.PROJECT_DESC = '33801-Urgent Care EnhancementEPDS V2'
              WHERE RPM2.EMP_ID = RF.EMP_ID 
             );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-23
    相关资源
    最近更新 更多