1

我有一个联系人表:

ID  NAME
--- ----
1   KK
2   JKI
3   HU

我有一个电话桌:

ID  ContactID  Phone  Type
--- ---------  -----  --------
1   1          569    Business
2   1          896    Mobile
3   1          258    Fax
4   2          369    Mobile
5   3          124    Fax
6   2          496    Fax

我想获取至少有一个电话号码的所有联系人。要显示的电话号码应该是商务,如果没有可用的商务类型,则为移动,如果没有可用的移动类型,则为传真,否则为空

样本结果:

ID  NAME   PHONE
--- ------ ------
1   KK     569   -- Business present
2   JKI    369   -- Business not present but mobile present
3   HU     124   -- only fax present
4

4 回答 4

4
;WITH [prior](i,t) AS 
(
    SELECT 1, 'Business'
    UNION ALL SELECT 2, 'Mobile'
    UNION ALL SELECT 3, 'Fax'
),
x AS 
(
  SELECT c.ID, c.Name, p.Phone,
    rn = ROW_NUMBER() OVER (PARTITION BY c.ID ORDER BY r.i)
  FROM dbo.Contacts AS c
  LEFT OUTER JOIN dbo.Phone AS p
  ON p.ContactID = c.ID
  LEFT OUTER JOIN [prior] AS r
  ON r.t = p.[Type]
)
SELECT ID, Name, Phone FROM x
WHERE rn = 1;

如果要消除没有电话的联系人,只需将两个实例都更改LEFT OUTERINNER

于 2012-06-21T22:36:53.403 回答
3
select  c.ID
,       c.Name
,       coalesce(business.Phone, mobile.Phone, fax.Phone) as Phone
from    Contacts c
left join
        Phone business
on      business.ContactID = c.ID
        and business.type = 'Business'
left join
        Phone mobile
on      mobile.ContactID = c.ID
        and mobile.type = 'Mobile'
left join
        Phone fax
on      fax.ContactID = c.ID
        and fax.type = 'Fax'
where   coalesce(business.Phone, mobile.Phone, fax.Phone) is not null
于 2012-06-21T22:30:14.913 回答
1

我能想到的最紧凑的解决方案是,

; WITH CTE AS (
    SELECT 
    c.ID, c.NAME, p.Phone
    , r = ROW_NUMBER()OVER(PARTITION BY c.ID ORDER BY CASE p.[TYPE] WHEN 'Business' THEN 1 WHEN 'Mobile' THEN 2 ELSE 3 END)
    FROM Contacts c
    LEFT JOIN Phone p ON p.ContactID = c.ID AND p.[TYPE] IN ('Business','Mobile','Fax')
    WHERE EXISTS(SELECT 1 FROM Phone WHERE ContactID = c.ID)
)
SELECT ID, NAME, Phone
FROM CTE
WHERE r = 1;

该解决方案返回,

  • 按指定顺序与第一个匹配电话的联系人
  • Contact with NULL phone # if a phone # 存在但没有指定类型
  • 根本没有电话的联系人没有结果
于 2012-06-22T02:18:44.653 回答
1

您的数据模型不适合有效地查询,但这可能会奏效:

SELECT C.ID, C.Name, COALESCE(
    (SELECT TOP 1 P.Phone FROM Phones P WHERE P.ContactID = C.ID AND P.[Type] = 'Business'),
    (SELECT TOP 1 P.Phone FROM Phones P WHERE P.ContactID = C.ID AND P.[Type] = 'Mobile'),
    (SELECT TOP 1 P.Phone FROM Phones P WHERE P.ContactID = C.ID AND P.[Type] = 'Fax')
  ) Phone
  FROM Contacts C
于 2012-06-21T22:30:01.267 回答