SQL 服务器 - 减少查询中列包含 NULL 的近乎重复的记录?

SQL Server - Mitigating near-duplicate records where columns contain NULL in a query?

上下文

我有一个 SQL 查询连接到直接显示结果的 Windows Forms DataGridView 的数据源。到目前为止,我已经设法让它获取所有联系人及其相关数据,但是有一个问题...

问题

由于 phone 及其类型在数据库中的保存方式,联系人显示时会显示与联系人关联的每个 phone 的新记录,我只需要它来显示每个 phone 类型的 'TOP 1'(如果存在)。

我尝试了几种我能想到并在互联网上找到的潜在解决方案,我尝试使用DISTINCT但它似乎对记录集没有任何影响,我也尝试了GROUP BY 但我最终遇到了问题,因为它需要聚合函数。

USE [Customer]

SELECT 
    co.[Contact ID] AS [ID], 
    co.[First Name] AS [First Name], 
    co.[Last Name] AS [Last Name], 
    cu.[Name] AS [Customer Name], 
    (SELECT TOP 1 te.[Number] WHERE tt.[Telephone Type] = 'Work') AS [Work Phone],
    (SELECT TOP 1 te.[Number] WHERE tt.[Telephone Type] = 'Mobile') AS [Mobile Phone],
    em.[Address] AS [Email Address]
FROM
    (
        (
            (
                (
                    (
                        (
                            ([Contact] AS co 
                             INNER JOIN 
                                 [Customer Contact] AS cc ON cc.[Contact ID] = co.[Contact ID]) 
                         INNER JOIN 
                             [Customer] AS cu ON cu.[Customer ID] = cc.[Customer ID]) 
                     INNER JOIN 
                         [Contact Email] AS ce ON ce.[Contact ID] = cc.[Contact ID]) 
                 INNER JOIN 
                 [Email] AS em ON em.[Email ID] = ce.[Email ID]) 
             INNER JOIN 
                 [Contact Telephone] AS ct ON ct.[Contact ID] = cc.[Contact ID]) 
         INNER JOIN 
             [Telephone] AS te ON te.[Telephone ID] = ct.[Telephone ID])
     INNER JOIN 
          [Telephone Type] AS tt ON tt.[Telephone Type ID] = ct.[Telephone Type ID])
--Only want to specify 'Work' and 'Mobile' out of the three phone types
WHERE 
    tt.[Telephone Type] <> 'Home' 
    --Specifying a single contact for the example
    AND co.[Last Name] = 'Wayne' 
ORDER BY 
    cu.[Name] ASC;

这是当前查询的记录集returns。

如您所见,两条记录有 NULL 个值不同。

ID First Name Last Name Customer Work Phone Mobile Phone Email Address
1 e002a448... Bruce Wayne Wayne Tech (worknumber) NULL bruce.wayne@waynetech.com
2 e002a448... Bruce Wayne Wayne Tech NULL (mobilenumber) bruce.wayne@waynetech.com

这是我正在尝试获取的记录集 - 如您所见,与联系人关联的第一个作品 phone 和手机 phone 包含在一个记录中,并且没有更多记录出现.

ID First Name Last Name Customer Work Phone Mobile Phone Email Address
1 e002a448... Bruce Wayne Wayne Tech (worknumber) (mobilenumber) bruce.wayne@waynetech.com

TLDR: 我不知道如何为数据库中的每个联系人显示单个记录,而不是为每个不同的关联 phone 每个联系人的编号。

您在查询中的某个时刻需要聚合或其他东西。我的建议是使用 OUTER APPLY:

SELECT co.[Contact ID] AS [ID], 
       co.[First Name] AS [First Name], 
       co.[Last Name] AS [Last Name], 
       cu.[Name] AS [Customer Name], 
       p.*
       em.[Address] AS [Email Address]
FROM [Contact] co JOIN 
     [Customer Contact] cc
     ON cc.[Contact ID] = co.[Contact ID] JOIN
     [Customer] cu
     ON cu.[Customer ID] = cc.[Customer ID] JOIN
     [Contact Email] ce
     ON ce.[Contact ID] = cc.[Contact ID] JOIN 
     [Email] em
     ON em.[Email ID] = ce.[Email ID] OUTER APPLY
     (SELECT MAX(CASE WHEN tt.[Telephone Type] = 'Work' THEN te.Number END) as work,
             MAX(CASE WHEN tt.[Telephone Type] = 'Mobile' THEN te.Number END) as mobile
             
      FROM [Contact Telephone] ct JOIN
           [Telephone] te
           ON te.[Telephone ID] = ct.[Telephone ID] JOIN
           [Telephone Type] tt
           ON tt.[Telephone Type ID] = ct.[Telephone Type ID]
      WHERE ct.[Contact ID] = cc.[Contact ID]
     ) p
--Only want to specify 'Work' and 'Mobile' out of the three phone types
WHERE co.[Last Name] = 'Wayne' 
ORDER BY cu.[Name] ASC;