无键连接表会导致错误的结果

时间:2017-12-17 23:21:26

标签: sql sql-server

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

#include <iostream>
#include <fstream>
#include <unordered_map>

std::string get_file_name(const std::string& s) {
  std::size_t first = s.find_first_of("\"");
  std::size_t last = s.find_last_of("\"");

  std::string request = s.substr(first, first - last);

  std::size_t file_begin = request.find_first_of(' ');
  std::string truncated_request = request.substr(++file_begin);

  std::size_t file_end = truncated_request.find(' ');
  std::string file_name = truncated_request.substr(0, file_end);

  return file_name;
}


int main() {

  std::ifstream f_s("header_log.txt");
  std::string content;
  std::unordered_map<std::string, int> file_access_counts;

  while (std::getline(f_s, content)) {
    auto file_name = get_file_name(content);
    auto item = file_access_counts.find(file_name);

    if (item != file_access_counts.end()) {
      ++file_access_counts.at(file_name);
    } else {
      file_access_counts.insert(std::make_pair(file_name, 1));
    }
  }

  f_s.close();

  std::ofstream ofs;
  ofs.open ("output.txt", std::ofstream::out | std::ofstream::app);

  for (auto& n: file_access_counts)
    ofs << n.first << ", " << n.second << std::endl;

  ofs.close();

  return 0;
}

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

但是考虑到这样的结构,有什么方法可以加入这两个表来获得部门吗?

由于最终程序的设计方式以及其他因素,使用内联子查询不是一种选择。

对此有何想法?

预期产出:

     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      

1 个答案:

答案 0 :(得分:1)

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

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 

<强> 注意:

这假设一个&#34;不区分大小写&#34;整理顺序。否则,john smith行将永远不会加入(因为'Manager'不匹配'manager'

同样,表2中的两个tina taylor行与'hr' vs 'HR'不同,但如果整理顺序不区分大小写,则不会因为没有&#34;材料&#34;行之间的差异。

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