【问题标题】:Joining tables without keys causes incorrect results连接没有键的表会导致不正确的结果
【发布时间】:2017-12-18 09:03:07
【问题描述】:

我有 2 个表 - 一个主表和另一个查找表。两者都没有任何钥匙。表结构如下。

     first name last name   role     location   Compensation Level  state
      john       smith      Manager     LA         A                 CA
      john       smith      Manager     BOS        B                 MA
      super      smither    developer   LA         B                 CA
      tina       taylor     supervisor  SFO        A                 CA
      tina       taylor     supervisor  BOS        B                 MA


     first name  last name  role        dept        
     john         smith     manager     finance     
     john         smith     manager     hr      
     super        smither   developer   PA      
     tina         taylor    supervisor  HR      
     tina         taylor    supervisor  hr      

非常可以理解,将两个表连接起来以获取名字、姓氏和角色组合的部门将导致不正确的结果,因为混合中涉及识别真正唯一记录的其他字段。

但是考虑到这样的结构,我有什么办法可以连接这两个表来获得部门?

由于最终过程的设计方式和其他因素,不能选择使用内联子查询。

对此有什么想法吗?

预期输出:

 first name last name   role     location   Compensation state dept
 john        smith      Manager    LA          A          CA finance
 john        smith      Manager    BOS         B          MA hr
 super       smither    developer  LA          B          CA PA
 tina        taylor     supervisor SFO         A          CA HR
 tina        taylor     supervisor  BOS        B          MA HR

【问题讨论】:

  • 您打算如何在没有任何密钥的情况下做到这一点?没有办法知道哪个约翰史密斯在那里。和蒂娜·泰勒一样。
  • 没有。这不是密钥本身的问题,而是没有办法唯一标识角色/部门。表 2 需要也在表 1 中的鉴别器
  • @DanGuzman 我没有,这就是当前设计的挑战。除非重新设计结构,否则无法判断我是否为员工分配了正确的部门。
  • 这是一个设计问题。你需要解决这个问题。否则没有解决办法
  • 解雇你的开发团队。从大炮里出来。

标签: sql sql-server


【解决方案1】:

这是一个给出确定性结果的示例,但它们是任意结果。它只是基于确定每个表中的“有序位置”,以便可以做出选择,并且每次执行查询时该选择都相同,但无法知道选择是否正确。

WITH
   sorted_t1 AS
(
    SELECT
        *,
        ROW_NUMBER() OVER (PARTITION BY first_name, last_name, role
                               ORDER BY compensation_level, location, state)  AS discriminator
    FROM
        t1
)
,
   sorted_t2 AS
(
    SELECT
        *,
        ROW_NUMBER() OVER (PARTITION BY first_name, last_name, role
                               ORDER BY dept)  AS discriminator
    FROM
        t2
)
SELECT
    *
FROM
    sorted_t1    t1
FULL OUTER JOIN
    sorted_t2    t2
        ON  t1.first_name    = t2.first_name
        AND t1.last_name     = t2.last_name
        AND t1.role          = t2.role
        AND t1.discriminator = t2.discriminator 

注意事项:

这假定一个“不区分大小写”的排序规则序列。否则john smith 行将永远不会加入(因为'Manager' 不会匹配'manager'

同样,表 2 中的两个 tina taylor 行是不同的'hr''HR',但如果排序顺序不区分大小写,则加入哪个并不重要到哪个,因为行之间没有“实质性”差异。

还值得注意的是,在上面的示例中,没有真正的理由假设来自洛杉矶的'John Smith' 位于finance 中。该查询只是强制该关联,因为在ROW_NUMBER() 中选择了ORDER BY。这意味着在使用这种技术时,您确实应该使用其他字段,即意味着彼此相关的某些东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-07
    • 1970-01-01
    • 2014-11-27
    • 2019-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-29
    相关资源
    最近更新 更多