匹配2波。第二个" Wave"基于First" Wave"

时间:2016-11-16 20:06:45

标签: sql-server sql-server-2012

我有一个"匹配"我需要匹配表中记录的场景。

为了便于说明,我改变了我的情况以使用Northwind数据库。

给出" set"数据(放在我下面的@holder表中),我需要根据以下标准找到匹配项。

  

如果姓氏和名字都匹配,则匹配以下两项或多项:(城市一起或拉链),电话,分机

     

如果姓氏或名字中的一个匹配,则匹配三个或更多以下内容:(城市一起或拉链),电话,   扩展

请注意"城邦联合或拉链"意味着我需要匹配城市和州的组合........或zip ..........如果所有三个匹配,(city-state-and-zip) ,这应该只算作" 1" for"(ColumnCityStateZipEnum + ColumnHomePhoneEnum + ColumnExtensionEnum)"计算

我想出了以下内容。但我有 7 左连接。

在SQL中还有另一种方法可以解决这类问题吗?

Use Northwind /* Or NorthwindPartial */
GO

declare @holder table ( holderidentitykey int identity (1,1), lastname varchar(32) , firstname varchar(48) , city varchar(32) , stateabbr varchar(32) , zip varchar(5) , homephone varchar(16) , extension varchar(8) )

insert into @holder ( lastname , firstname , city , stateabbr, zip, homephone , extension )
select null , null, null, null, null , null, null
union all select 'Davolio' , 'Nancy', null, null, '98122' , '(206) 555-9857', null /* should 'match'.  lastname, firstname and TWO of the other data-elements */
union all select 'Davolio' , null, null, null, null , null, null
union all select 'Fuller' , 'Andrew', 'Tacoma', 'WA', null , null, null
union all select 'Peacock' , 'MaggyNotAMatchNoPhone', 'Redmond', 'WA', '98052' , null, null
union all select 'Peacock' , 'MaggyNotAMatchWithPhoneAndExtension', 'Redmond', 'WA', '98052' , '(206) 555-8122', '5176' /* should 'match'.  lastname and THREE of the other data-elements */

/* 

    If both lastname and firstname match, match on TWO or more of the following : (city-state-together OR zip) , phone, extension

    If one of either lastname OR firstname match, match on THREE or more of the following : (city-state-together OR zip) , phone, extension
*/


select distinct * from
(
    select
    holderidentitykey,
    ColumnLastNameFirstNameEnum = 
        case
            when h.lastname = eLastName.LastName and h.firstname = eFirstName.FirstName then 2
            when h.lastname = eLastName.LastName then 1
            when h.firstname = eFirstName.FirstName then 1
            else 0
        end
, 
    ColumnCityStateZipEnum = 
        case
            when h.zip = eZip.PostalCode then 1
            when h.city = eCity.City and h.stateabbr = eState.Region then 1
            else 0
        end
, 
    ColumnHomePhoneEnum = 
        case
            when h.homephone = eHomePhone.HomePhone then 1
            else 0
        end
, 
    ColumnExtensionEnum = 
        case
            when h.extension = eExtension.Extension then 1
            else 0
        end
    , eLastName.LastName , eFirstName.FirstName, eZip.PostalCode, eCity.City, eState.Region, eHomePhone.HomePhone, eExtension.Extension
    from
    @holder h 
    left join dbo.Employees eLastName on h.lastname = eLastName.LastName 
    left join dbo.Employees eFirstName on h.firstname = eFirstName.FirstName
    left join dbo.Employees eZip on h.zip = eZip.PostalCode
    left join dbo.Employees eCity on h.city = eCity.City
    left join dbo.Employees eState on h.stateabbr = eState.Region
    left join dbo.Employees eHomePhone on h.homephone = eHomePhone.HomePhone
    left join dbo.Employees eExtension on h.extension = eExtension.Extension
) as derived1
where 
    derived1.ColumnLastNameFirstNameEnum >= 2 and (ColumnCityStateZipEnum + ColumnHomePhoneEnum + ColumnExtensionEnum) >= 2
    OR
    derived1.ColumnLastNameFirstNameEnum >= 1 and (ColumnCityStateZipEnum + ColumnHomePhoneEnum + ColumnExtensionEnum) >= 3



-- select * from dbo.Employees e 

这是"部分"如果你没有方便的话,可以创造Northwind。

SET NOCOUNT ON
GO

USE master
GO
if exists (select * from sysdatabases where name='NorthwindPartial')
        drop database NorthwindPartial
go

DECLARE @device_directory NVARCHAR(520)
SELECT @device_directory = SUBSTRING(filename, 1, CHARINDEX(N'master.mdf', LOWER(filename)) - 1)
FROM master.dbo.sysaltfiles WHERE dbid = 1 AND fileid = 1

EXECUTE (N'CREATE DATABASE NorthwindPartial
  ON PRIMARY (NAME = N''NorthwindPartial'', FILENAME = N''' + @device_directory + N'northwndPartial.mdf'')
  LOG ON (NAME = N''NorthwindPartial_log'',  FILENAME = N''' + @device_directory + N'northwndPartial.ldf'')')
go


GO

set quoted_identifier on
GO

/* Set DATEFORMAT so that the date strings are interpreted correctly regardless of
   the default DATEFORMAT on the server.
*/
SET DATEFORMAT mdy
GO
use "NorthwindPartial"
go

if exists (select * from sysobjects where id = object_id('dbo.Employees') and sysstat & 0xf = 3)
    drop table "dbo"."Employees"
GO
CREATE TABLE "Employees" (
    "EmployeeID" "int" IDENTITY (1, 1) NOT NULL ,
    "LastName" nvarchar (20) NOT NULL ,
    "FirstName" nvarchar (10) NOT NULL ,
    "Title" nvarchar (30) NULL ,
    "TitleOfCourtesy" nvarchar (25) NULL ,
    "BirthDate" "datetime" NULL ,
    "HireDate" "datetime" NULL ,
    "Address" nvarchar (60) NULL ,
    "City" nvarchar (15) NULL ,
    "Region" nvarchar (15) NULL ,
    "PostalCode" nvarchar (10) NULL ,
    "Country" nvarchar (15) NULL ,
    "HomePhone" nvarchar (24) NULL ,
    "Extension" nvarchar (4) NULL ,
    "Photo" "image" NULL ,
    "Notes" "ntext" NULL ,
    "ReportsTo" "int" NULL ,
    "PhotoPath" nvarchar (255) NULL ,
    CONSTRAINT "PK_Employees" PRIMARY KEY  CLUSTERED 
    (
        "EmployeeID"
    ),
    CONSTRAINT "FK_Employees_Employees" FOREIGN KEY 
    (
        "ReportsTo"
    ) REFERENCES "dbo"."Employees" (
        "EmployeeID"
    ),
    CONSTRAINT "CK_Birthdate" CHECK (BirthDate < getdate())
)
GO
 CREATE  INDEX "LastName" ON "dbo"."Employees"("LastName")
GO
 CREATE  INDEX "PostalCode" ON "dbo"."Employees"("PostalCode")
GO


set quoted_identifier on
go
set identity_insert "Employees" on
go
ALTER TABLE "Employees" NOCHECK CONSTRAINT ALL
go
INSERT "Employees"("EmployeeID","LastName","FirstName","Title","TitleOfCourtesy","BirthDate","HireDate","Address","City","Region","PostalCode","Country","HomePhone","Extension","Photo","Notes","ReportsTo","PhotoPath") VALUES(1,'Davolio','Nancy','Sales Representative','Ms.','12/08/1948','05/01/1992','507 - 20th Ave. E.
Apt. 2A','Seattle','WA','98122','USA','(206) 555-9857','5467',null,'Education includes a BA in psychology from Colorado State University in 1970.  She also completed "The Art of the Cold Call."  Nancy is a member of Toastmasters International.',2,'http://accweb/emmployees/davolio.bmp')
GO
INSERT "Employees"("EmployeeID","LastName","FirstName","Title","TitleOfCourtesy","BirthDate","HireDate","Address","City","Region","PostalCode","Country","HomePhone","Extension","Photo","Notes","ReportsTo","PhotoPath") VALUES(2,'Fuller','Andrew','Vice President, Sales','Dr.','02/19/1952','08/14/1992','908 W. Capital Way','Tacoma','WA','98401','USA','(206) 555-9482','3457',null,'Andrew received his BTS commercial in 1974 and a Ph.D. in international marketing from the University of Dallas in 1981.  He is fluent in French and Italian and reads German.  He joined the company as a sales representative, was promoted to sales manager in January 1992 and to vice president of sales in March 1993.  Andrew is a member of the Sales Management Roundtable, the Seattle Chamber of Commerce, and the Pacific Rim Importers Association.',NULL,'http://accweb/emmployees/fuller.bmp')
GO
INSERT "Employees"("EmployeeID","LastName","FirstName","Title","TitleOfCourtesy","BirthDate","HireDate","Address","City","Region","PostalCode","Country","HomePhone","Extension","Photo","Notes","ReportsTo","PhotoPath") VALUES(3,'Leverling','Janet','Sales Representative','Ms.','08/30/1963','04/01/1992','722 Moss Bay Blvd.','Kirkland','WA','98033','USA','(206) 555-3412','3355',null,'Janet has a BS degree in chemistry from Boston College (1984).  She has also completed a certificate program in food retailing management.  Janet was hired as a sales associate in 1991 and promoted to sales representative in February 1992.',2,'http://accweb/emmployees/leverling.bmp')
GO
INSERT "Employees"("EmployeeID","LastName","FirstName","Title","TitleOfCourtesy","BirthDate","HireDate","Address","City","Region","PostalCode","Country","HomePhone","Extension","Photo","Notes","ReportsTo","PhotoPath") VALUES(4,'Peacock','Margaret','Sales Representative','Mrs.','09/19/1937','05/03/1993','4110 Old Redmond Rd.','Redmond','WA','98052','USA','(206) 555-8122','5176',null,'Margaret holds a BA in English literature from Concordia College (1958) and an MA from the American Institute of Culinary Arts (1966).  She was assigned to the London office temporarily from July through November 1992.',2,'http://accweb/emmployees/peacock.bmp')
GO
INSERT "Employees"("EmployeeID","LastName","FirstName","Title","TitleOfCourtesy","BirthDate","HireDate","Address","City","Region","PostalCode","Country","HomePhone","Extension","Photo","Notes","ReportsTo","PhotoPath") VALUES(5,'Buchanan','Steven','Sales Manager','Mr.','03/04/1955','10/17/1993','14 Garrett Hill','London',NULL,'SW1 8JR','UK','(71) 555-4848','3453',null,'Steven Buchanan graduated from St. Andrews University, Scotland, with a BSC degree in 1976.  Upon joining the company as a sales representative in 1992, he spent 6 months in an orientation program at the Seattle office and then returned to his permanent post in London.  He was promoted to sales manager in March 1993.  Mr. Buchanan has completed the courses "Successful Telemarketing" and "International Sales Management."  He is fluent in French.',2,'http://accweb/emmployees/buchanan.bmp')
GO
INSERT "Employees"("EmployeeID","LastName","FirstName","Title","TitleOfCourtesy","BirthDate","HireDate","Address","City","Region","PostalCode","Country","HomePhone","Extension","Photo","Notes","ReportsTo","PhotoPath") VALUES(6,'Suyama','Michael','Sales Representative','Mr.','07/02/1963','10/17/1993','Coventry House
Miner Rd.','London',NULL,'EC2 7JR','UK','(71) 555-7773','428',null,'Michael is a graduate of Sussex University (MA, economics, 1983) and the University of California at Los Angeles (MBA, marketing, 1986).  He has also taken the courses "Multi-Cultural Selling" and "Time Management for the Sales Professional."  He is fluent in Japanese and can read and write French, Portuguese, and Spanish.',5,'http://accweb/emmployees/davolio.bmp')
GO
INSERT "Employees"("EmployeeID","LastName","FirstName","Title","TitleOfCourtesy","BirthDate","HireDate","Address","City","Region","PostalCode","Country","HomePhone","Extension","Photo","Notes","ReportsTo","PhotoPath") VALUES(7,'King','Robert','Sales Representative','Mr.','05/29/1960','01/02/1994','Edgeham Hollow
Winchester Way','London',NULL,'RG1 9SP','UK','(71) 555-5598','465',null,'Robert King served in the Peace Corps and traveled extensively before completing his degree in English at the University of Michigan in 1992, the year he joined the company.  After completing a course entitled "Selling in Europe," he was transferred to the London office in March 1993.',5,'http://accweb/emmployees/davolio.bmp')
GO
INSERT "Employees"("EmployeeID","LastName","FirstName","Title","TitleOfCourtesy","BirthDate","HireDate","Address","City","Region","PostalCode","Country","HomePhone","Extension","Photo","Notes","ReportsTo","PhotoPath") VALUES(8,'Callahan','Laura','Inside Sales Coordinator','Ms.','01/09/1958','03/05/1994','4726 - 11th Ave. N.E.','Seattle','WA','98105','USA','(206) 555-1189','2344',null,'Laura received a BA in psychology from the University of Washington.  She has also completed a course in business French.  She reads and writes French.',2,'http://accweb/emmployees/davolio.bmp')
GO
INSERT "Employees"("EmployeeID","LastName","FirstName","Title","TitleOfCourtesy","BirthDate","HireDate","Address","City","Region","PostalCode","Country","HomePhone","Extension","Photo","Notes","ReportsTo","PhotoPath") VALUES(9,'Dodsworth','Anne','Sales Representative','Ms.','01/27/1966','11/15/1994','7 Houndstooth Rd.','London',NULL,'WG2 7LT','UK','(71) 555-4444','452',null,'Anne has a BA degree in English from St. Lawrence College.  She is fluent in French and German.',5,'http://accweb/emmployees/davolio.bmp')
go
set identity_insert "Employees" off
go
ALTER TABLE "Employees" CHECK CONSTRAINT ALL
go
set quoted_identifier on
go


Select * from "Employees"

1 个答案:

答案 0 :(得分:1)

分析您的匹配规则可能会有所帮助,如果我们将其分解,我们可以看到匹配的不可协商条件是FirstName或{{1} } 火柴。因此,让我们构建一个查询,我们只加入employee表中的那些行:

LastName

现在我们只查看符合最低标准的行,我们可以评估其他行。基本上您的规则是,如果... FROM @holder As h JOIN Employee As e ON h.FirstName = e.FirstName OR h.LastName = e.LastName ... FirstName匹配,那么我们至少需要以下三种(假设我们匹配LastName):

  • 匹配FirstName
  • 匹配LastNameCity,或State
  • 匹配PostalCode
  • 匹配HomePhone

根据ExtensionFirstName是否匹配,您会提出不同的规则,但只要您拥有这两个中的一个,那么从我和我的角度来看规则在数学上是等价的。我带着。

因此,我们可以获取潜在的匹配行,并计算其中有多少匹配属性,并过滤掉那些不够的行。

LastName

请注意,如果你有大型表(1M +)并希望经常匹配,这种方法可能无法很好地扩展,但如果/当这些情况发生时,你可以看看重构。