【问题标题】:SQL comparing two sets of complex dataSQL比较两组复杂数据
【发布时间】:2018-04-08 23:30:07
【问题描述】:

抱歉,标题可能不是最好的,但我希望您能理解我遇到的问题。

我需要比较和分析两组数据,为此我正在使用 MS-Access。我的数据组织在两个表中。以下不是我正在使用的真实数据,但可以作为示例:

表 1

ID  Name
1   Zoie
2   Rohan
2   Simon
3   Jerome
4   Jakob
4   Mathew
4   Cora
6   Keely
7   Aiyana
7   Jake
8   Reid
9   Emerson

表 2

ID  Name
1   Michael
2   Rohan
2   Simon
3   Jill
4   Jakob
4   Cora
5   Charlie
7   John
8   Reid
9   Yadiel
9   Emerson
9   Paris
  1. 所以,我只需要选择两个表中完全对应的那些 ID(特定 ID 下的所有名称都相同),它们是:2 和 8

  2. 我还希望有单独的 select 语句,这将导致 ID 2 和 8 以及来自表 1 的名称的 ID 也出现在表 2 中(全部来自表 1 加上可能在表 2 下的一些额外内容同一个ID)。所以这将是:2、8、9

  3. 我还希望有单独的 select 语句,这将产生 ID 2 和 8 以及来自表 2 的名称的 ID,这些 ID 也出现在表 1 中(全部来自表 2 加上可能在表 1 下的一些额外内容同一个ID)。所以这将是:2、4、8

  4. 我还希望有单独的选择语句,它将是最后两个的组合。 所以结果是:2、4、8、9

如果有任何建议,我将不胜感激。 提前致谢! 最好的祝福, 马里奥

【问题讨论】:

  • 到目前为止您尝试过什么?你有什么问题吗?
  • 我根本不知道怎么做这个sql语句,也不知道怎么表达自己,在网上搜索解决方案。如果我能找到一些类似的例子,我相信我可以将它应用到我的例子中。
  • 家庭作业,对吧?你应该提供什么类型的答案?只是一个完成的清单? SQL? VBA?一个完整的数据库?本章的前几部分涵盖了哪些内容? (我不会将名称列表称为“复杂数据”!)
  • 学习过程的一部分是亲自尝试。当你开始做这件事并自己取得成就时,你会更有信心。这并不容易,但看看耐克。去做吧。
  • 感谢两位的建议。实际上,它不是为了家庭作业,而是为了一份真正的工作。我知道一些非常基本的 SQL,但我不是程序员或高级数据库用户,而且我不会每天都这样做。当需要做这样的事情(excel 和 access)时,我主要使用 MS 办公工具,但通常我必须在表格中 1:1 比较数据,所以我不知道如何解决这个问题。我需要将此分析作为更大工作的一小部分(以深入了解数据并就进一步的步骤做出一些决定)。

标签: sql ms-access compare


【解决方案1】:

Q#1:

select id
from table1
group by id
having count(*) =
(
  select count(*)
  from table2
  group by table2.id
  having table2.id = table1.id
) 
and count(*) = 
(
  select count(*)
  from table1 table1_1
  inner join table2 on table1_1.id = table2.id and table1_1.name = table2.name
  group by table1_1.id
  having table1_1.id = table1.id
) 

这个查询的解释:

  • 它是按 ID 对 table1 进行分组
  • 对于每个组(每个 ID),它会计算 table1 中具有此 ID 的行数。
  • 对于每个组,它会计算 table2 中具有此 ID 的行数。
  • 对于每个组,它计算名称出现在此 ID 的两个表中的行数(它通过inner joining table1 和 table2 在 ID 和名称上执行此操作,这意味着只有 ID 和名称同时出现的行对于每个 ID,都会计算两个表中的匹配项)。
  • 然后它返回 ID(来自 table1),其中上述每个计数都相等。这会导致返回所有名称都在两个表中的 ID(不多也不少)。

Q#2 - 在这种情况下,您不关心 table2 每个 ID 具有相同数量的名称。所以删除第一个子查询(计算 table2 中的匹配行)。

select id
from table1
group by id
having count(*) = 
(
  select count(*)
  from table1 table1_1
  inner join table2 on table1_1.id = table2.id and table1_1.name = table2.name
  group by table1_1.id
  having table1_1.id = table1.id
) 

尽管遵循与 Q#1 相同的逻辑,上述内容很容易理解,但执行以下操作可能更有效,更直接。仅当您发现它对于您的数据而言运行速度太慢时才有意义(这是主观的和上下文相关的)。

select table1.id
from table1
left join table2 on table1.id = table2.id and table1.name = table2.name
group by table1.id
having count(table1.id) = count(table2.id)

这里,两个表是LEFT(外部)连接的,这意味着 table1 中的所有记录都被收集,table2 中通过 ID 和 Name 匹配的记录也被包含在旁边。然后,我们按 ID 对它们进行分组,并将 table1 中每个组的计数与 table2 中具有匹配名称的组进行比较。

Q#3 - 除了 table1 和 table2 交换之外,这种情况与 Q#2 相同。

Q#4 - 在这种情况下,您只关心至少有一个名称同时出现在两个表中的 ID。所以加入表格并返回不同的 ID:

select distinct id
from table1 
inner join table2 on table1.id = table2.id and table1.name = table2.name

这是一个包含四个查询的 SQLFiddle:http://www.sqlfiddle.com/#!18/3fc71/22

【讨论】:

  • 安德鲁,非常感谢您的努力(为我提供示例和解释)!效果很好!在我的电脑和 65000 行的表上速度有点慢,但这是一次性分析,所以等待半小时是没有问题的。
  • 在发现您没有做作业后,我用更多细节(而不仅仅是提示)编辑了答案:)。
  • 再次感谢!我将您的整个答案保存为任何类似的未来任务的食谱。对于这个 sqlfiddle 也是一个不错的提示!
  • 我添加了一个可能更快的 Q2 版本。
猜你喜欢
  • 2020-09-26
  • 2011-02-15
  • 2011-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多