必须在nvarchar字段上连接没有外键的数据库表,从而产生多个不存在的行

时间:2010-12-07 04:46:08

标签: sql-server-2005 database-design datatable foreign-keys

摘要

好的,早在2007年我就被要求制作一个小软件,目的是根据当地电话簿输入人名,地址和电话号码。

目前,唯一的要求是能够按街道名称对此列表进行分组。因此,地址中的街道名称就足够了。

现在已经是第三年了,每年一次,我一直在努力将街道名称和行业重新统一起来。一个只有“市中心”,“上层城市”,“125e”,“超过125e”和“未知”的街道,我无法分类。

数据样本和结构

我有一个初始表,它是在第一次交付软件时创建的。我将其作为SQL Server,因为我将数据导入其中以便于工作。

CREATE TABLE Contacts (
    ContactId int not null identity(1, 1) primary key
    , lastname nvarchar(50) not null
    , firstname nvarchar(20) not null
    , civic nvarchar(10) not null
    , street nvarchar(20) not null
    , city nvarchar(20) not null
    , phone bigint not null
)

-- With the following sample data:

insert into Contacts (lastname, firstname, civic, street, city, phone)
    values (N'LNAME-5551231234', N'A', N'89', N'MY STREET', N'SHAWINIGAN', 5551231234)
GO
insert into Contacts (lastname, firstname, civic, street, city, phone)
    values (N'LNAME-5559879876', N'FNAME', N'10', N'YOUR STREET', N'SHAWINIGAN', 5559879876)
GO
insert into Constacts (lastname, firstname, civic, street, city, phone)
    values (N'LNAME-5554564567', N'AFNAME', N'25', N'HIS STREET', N'SHAWINIGAN-SUD', 5554564567)
GO

然后,我添加了正确编写了街道名称的表格,以及不同部门的另一个表格。

-- Sectors
CREATE TABLE Sectors (
    sectorId int not null identity(1, 1) primary key
    , sectorName nvarchar(20) not null
)
GO

insert into Sectors (sectorName)
    values (N'Downtown')
GO
insert into Sectors (sectorName)
    values (N'Upper city')
GO

-- Streets
CREATE TABLE Streets (
    streetId int not null identity(1, 1) primary key
    , sectorId int not null references Sectors (sectorId)
    , streetName nvarchar(20) not null
)
GO

insert into Streets (sectorId, streetName)
    values (1, N'My St.')
GO
insert into Streets (sectorId, streetName)
    values(1, N'Ur Street')
GO
insert into Streets (sectorId, streetName)
    values (2, N'HIS STREET')
GO

为了解释的利益,这将导致:

Sectors
sectorId | sectorName
---------------------
   1     | Downtown
   2     | Upper city

Streets
streetId | sectorId | streetName
--------------------------------
   1     |    1     | My St.
   2     |    1     | Ur Street
   3     |    2     | HIS STREET

Contacts
contactId |     lastname     | firstname | civic |   street    |      city      |   phone
--------------------------------------------------------------------------------------------
    1     | LNAME-5551231234 | A         | 89    | My Street   | SHAWINIGAN     | 5551231234
    2     | LNAME-5559879876 | FNAME     | 10    | Your Street | SHAWINIGAN     | 5559879876
    3     | LNAME-5554564567 | AFNAME    | 25    | HIS STREET  | SHAWINIGAN-SUD | 5554564567

目标

由于正字法,我得解决街道名称冲突。首先,字段Contacts.street似乎包含Streets.streetName中存在的一个值。因此,当我与一个相等的(=)符号进行比较时,我只得到大约6,000行,当时这个城市的人口大约是13,000人。

因此,我尝试使用 like 子句加入表格,但是我可以收集大约20,000行,其中包含来自{{1}的重复的姓氏,姓名,思域,电话信息组合}。

除此之外,我似乎缺乏精确度或者不知道怎么说,但是当我使用之类的时,我得到了一些奇怪的结果。

例如,获得的结果是让我们考虑Contacts中的街道 125e Rue ,并且 12e Rue 25e Rue在Streets,然后看起来联系人是重复的,因为两条街道都符合之类的模式。 (生产数据理解起来会容易得多,但这些是地址和电话号码,所以我不能......)

到目前为止受到诱惑的查询

此查询产生上述重复信息的类型,但只有来自Contacts的重复信息,因为Contacts在此查询范围内从记录更改为另一个记录。此外,此查询会查看信息,例如,如果 A LASTNAME-5551231234 有多个地址。

Streets.streetName

另一个查询,当我们从select c.city , s.sectorName , st.streetName , c.civic , c.lastname , c.firstname , c.phone from Contacts c inner join Streets st on st.streetName like N'%' + c.street + N'%' inner join Sectors s on s.sectorId = st.sectorId group by c.city , s.sectorName , st.streetName , c.civic , c.lastname , c.firstname , c.phone order by c.city , s.sectorName , st.streetName , c.civic , c.lastname 表中删除尽可能多的信息时,我希望从中获得灵感,因为它看起来会产生正确的结果。

最后,我很困惑自己,我不希望你们中的一个,专业开发人员和DBA,可以帮助我一个简单的答案,但是通过演练和实证方法,所以我愿意尝试一下你可能没想过的任何事情。

感谢您提供的任何帮助。 =)

1 个答案:

答案 0 :(得分:1)

肯定不会这么简单......

select c.city
        , s.sectorName
        , st.streetName
        , c.civic
        , c.lastname
        , c.firstname
        , c.phone
    from Contacts c
        OUTER JOIN Streets st on st.streetName = c.street
        inner join Sectors s on s.sectorId = st.sectorId
    group by c.city
        , s.sectorName
        , st.streetName
        , c.civic
        , c.lastname
        , c.firstname
        , c.phone
    order by c.city
        , s.sectorName
        , st.streetName
        , c.civic
        , c.lastname