【问题标题】:Filtering SELECT TOP WITH TIES When No Records Exist for a Specific Column当特定列不存在记录时过滤 SELECT TOP WITH TIES
【发布时间】:2018-11-27 23:25:38
【问题描述】:

问题:如何过滤我的结果(见下文)以排除错误数据?我猜我的问题出在 WHERE 子句中的某个地方,但对于我的生活,我无法弄清楚。

最终目标:portfolioe_component 表中不存在值的情况下,为CDA_Orientation 列返回NULL 值(例如,员工还没有入职培训)

数据库架构:

有错误的结果集:

注意:Eastman、DeLuca 和 Fontano 的迎新日期是相同的日期,代表 portfolio 表的 course_startdate 列的 TOP 1 结果。

我希望结果是什么样的:

如果我的 JOINS 操作正确,CDA_Orientation 列应该显示 NULL,因为 portfolio 表中没有条目(因此, e_component table) 这三个人。只有当员工被分配到课程时,该条目才由前端创建

这是我的代码:

SELECT TOP (1) WITH TIES
    P.lastname+', '+P.firstname AS Employee,
    P.person_id,
    CONVERT(DATE,PC.CDAI_EXP_DATE) AS CDA_Infant,
    CONVERT(DATE,PC.CDAP_EXP_DATE) AS CDA_Preschool,
    CONVERT(DATE,PO.course_startdate) AS CDA_Orientation

FROM person P
    JOIN person_custom PC ON PC.person_id=P.person_id
    LEFT JOIN portfolio PO ON P.person_id=PO.person_id
    FULL JOIN e_component EC ON PO.component_id=EC.component_id

WHERE (cdai_exp_date IS NOT NULL OR cdap_exp_date IS NOT NULL)
    AND PO.course_startdate IN (SELECT course_startdate
        FROM portfolio PO
        LEFT JOIN e_component EC ON PO.component_id=EC.component_id
        WHERE (EC.userdefined_id LIKE '000150%' AND PO.status=11))

ORDER BY ROW_NUMBER() OVER(PARTITION BY P.lastname+', '+P.firstname 
    ORDER BY PO.person_id)

注意:TOP (1) WITH TIES 已成功从 Tarkin 和 Rust 的portfolio 表中提取最新的入职培训日期(员工可以有多个)。我已经删除了所有不必要的 JOINS 和警告。

提前致谢!

【问题讨论】:

  • 要明确:您是说您粘贴的确切查询会产生您所说的不正确的确切结果吗?因为如果 person_id 不存在于投资组合表中,我看不出您当前的查询是如何实现的。
  • 问题在于 person_ids 的 Eastman、DeLuca 和 Fontano 确实存在于 portfolio 表中 - 但是对于 component_ids 相关联>'000150%'。否则,这会简单得多。在这个系统中,比如我自己的person_idportfolio表中出现了14次。

标签: sql sql-server tsql join


【解决方案1】:

我认为连接是问题所在。如果您只是想为每个人获取记录,那么以这种方式使用 WITH TIES 也会令人困惑;我会使用GROUP BY。如果你想在没有子查询的情况下这样做,你可以这样做:

SELECT
    P.lastname+', '+P.firstname AS Employee,
    P.person_id,
    CONVERT(DATE,PC.CDAI_EXP_DATE) AS CDA_Infant,
    CONVERT(DATE,PC.CDAP_EXP_DATE) AS CDA_Preschool,
    MAX(CONVERT(DATE,PO.course_startdate)) AS CDA_Orientation
FROM @person P
JOIN @person_custom PC 
ON PC.person_id=P.person_id
LEFT JOIN 
    (@portfolio PO 
    JOIN @e_component EC 
    ON PO.component_id=EC.component_id
        AND EC.userdefined_id LIKE '000150%' 
        AND PO.status=11)
ON P.person_id=PO.person_id
WHERE (cdai_exp_date IS NOT NULL OR cdap_exp_date IS NOT NULL)
GROUP BY P.lastname, P.firstname, P.person_id,PC.CDAI_EXP_DATE,PC.CDAP_EXP_DATE

【讨论】:

  • 非常感谢您!澄清关于JOINs 的问题(因为我还是SQL 新手):如果没有SELECT 语句,LEFT JOIN 子查询如何可能?这太棒了,我想根据我的其他查询对其进行调整。
  • @LexLuthor 这不是子查询(括号在这里实际上不是必需的 - 没有它们,查询将是相同的 - 但它们使它更容易理解)。它只是嵌套连接。您可能可以通过搜索“嵌套连接”找到有关此的一些信息。
猜你喜欢
  • 2020-07-21
  • 2012-03-26
  • 2021-12-25
  • 1970-01-01
  • 2014-04-05
  • 1970-01-01
  • 1970-01-01
  • 2011-01-30
相关资源
最近更新 更多