Tsql 使用;“联合所有人”;及;分组方式;实施";“相交”;

Tsql 使用;“联合所有人”;及;分组方式;实施";“相交”;,tsql,intersect,Tsql,Intersect,我提供了以下查询来查找两个数据集中的公共记录,但我很难确定查询的正确性,因为我的数据库中有很多数据记录 是否可以使用UNION ALL在“客户”和“员工”表之间执行Intersect,并对如下结果应用GROUP BY SELECT D.Country, D.Region, D.City FROM (SELECT DISTINCT Country, Region, City FROM Customers UNION ALL SELECT

我提供了以下查询来查找两个数据集中的公共记录,但我很难确定查询的正确性,因为我的数据库中有很多数据记录

是否可以使用
UNION ALL
在“客户”和“员工”表之间执行
Intersect
,并对如下结果应用
GROUP BY

SELECT D.Country, D.Region, D.City
  FROM (SELECT DISTINCT Country, Region, City 
          FROM Customers
         UNION ALL
        SELECT DISTINCT Country, Region, City
          FROM Employees) AS D
GROUP BY D.Country, D.Region, D.City
HAVING COUNT(*) = 2;
因此,我们是否可以说,此查询结果中存在的任何记录也存在于“客户和员工”表之间的
Intersect
集合中
Intersect
集合中“客户和员工”之间的任何记录中表也将在该查询的结果中

所以说这个查询的结果中的任何记录都是正确的吗 在“客户和员工”和“任何 存在于“客户和员工”之间的“相交”集合中是结果 这个问题的答案是什么

是。

。。。是的,但是它不会那么有效,因为你要过滤掉重复的内容三次而不是一次。在您的查询中,您是

  • 使用DISTINCT从员工中提取唯一记录
  • 使用DISTINCT从客户中提取唯一记录
  • 使用UNIONALL组合两个查询
  • 在外部查询中使用GROUP BY筛选在步骤1、2和3中检索到的记录 使用INTERSECT将返回相同的结果,但效率更高。要亲自查看,您可以创建下面的示例数据并运行两个查询:

    use tempdb
    go
    if object_id('dbo.customers') is not null drop table dbo.customers;
    if object_id('dbo.employees') is not null drop table dbo.employees;
    
    create table dbo.customers
    (
      customerId int identity,
      country    varchar(50),
      region     varchar(50),
      city       varchar(100)
    );
    
    create table dbo.employees
    (
      employeeId int identity,
      country    varchar(50),
      region     varchar(50),
      city       varchar(100)
    );
    
    insert dbo.customers(country, region, city) 
    values ('us', 'N/E', 'New York'), ('us', 'N/W', 'Seattle'),('us', 'Midwest', 'Chicago');
    insert dbo.employees
    values ('us', 'S/E', 'Miami'), ('us', 'N/W', 'Portland'),('us', 'Midwest', 'Chicago');
    
    运行以下查询:

    SELECT D.Country, D.Region, D.City
    FROM 
    (
      SELECT DISTINCT Country, Region, City 
      FROM Customers
      UNION ALL
      SELECT DISTINCT Country, Region, City
      FROM Employees
    ) AS D
    GROUP BY D.Country, D.Region, D.City
    HAVING COUNT(*) = 2;
    
    SELECT Country, Region, City
    FROM dbo.customers
    INTERSECT
    SELECT Country, Region, City
    FROM dbo.employees;
    
    结果:

    Country     Region     City
    ----------- ---------- ----------
    us          Midwest    Chicago
    
    Country     Region     City
    ----------- ---------- ----------
    us          Midwest    Chicago
    
    如果使用INTERSECT不是一个选项,或者您想要更快的查询,您可以通过两种不同的方式改进您发布的查询,例如:

    选项1:让GROUP BY按如下方式处理所有重复数据消除:

    这与您发布的内容相同,但没有区别

    SELECT D.Country, D.Region, D.City
    FROM 
    (
      SELECT Country, Region, City 
      FROM Customers
      UNION ALL
      SELECT Country, Region, City
      FROM Employees
    ) AS D
    GROUP BY D.Country, D.Region, D.City
    HAVING COUNT(*) = 2;
    
    选项2:使用行号

    这将是我的偏好,可能是最有效的

    SELECT Country, Region, City
    FROM 
    (
      SELECT
        rn = row_number() over (partition by D.Country, D.Region, D.City order by (SELECT null)), 
        D.Country, D.Region, D.City
      FROM 
      (
        SELECT Country, Region, City 
        FROM Customers
        UNION ALL
        SELECT Country, Region, City
        FROM Employees
      ) AS D
    ) uniquify
    WHERE rn = 2;
    

    结果会给你你想要的。两个表中都有相同的国家、地区和城市。通常你会用一个不同的内部连接或in语句来模拟INTERSECT。也许这有助于@RaymondNijland——他在两个表中都做了一个不同的操作。所以每个国家、地区、城市在两个表中只能有一个记录。谢谢你们的帮助。嗨,艾伦,谢谢你们的回复。你完全正确。