【问题标题】:Left Outer Join with one result per match and "priority" of match set by a different field in match SQL Server 2005左外连接,每次匹配一个结果,匹配的“优先级”由匹配 SQL Server 2005 中的不同字段设置
【发布时间】:2012-02-03 18:02:27
【问题描述】:

我试图在左外连接中获得每个匹配 (CONTACT_ID) 的单个结果 (PHONE)。我想有一种方法可以通过另一个列/字段(电话类型(TYPE))设置的偏好(或顺序)来完成此操作,但我无法弄清楚。下面是一个事实列表,以帮助更好地解释我想要完成的事情,然后下面是一个示例表 A 和 B 以及所需的结果。我看过 min() 和 group by,但我不知道如何在这里工作。附带说明一下,在这工作之后,我将以更简单的方式将它加入到左侧的更多表格中。

  • 学生可以拥有无​​限数量的 CONTACT_ID。
  • 联系人并不总是拥有所有电话类型。
  • 电话类型 (TYPE) 的首选顺序是 C、H、W(幸运的是,它们恰好是字母顺序)
  • 如果 PHONE 为空,则忽略匹配并转到下一个优先级

表A:

STUDENT_ID  CONTACT_ID
----------  ----------
X           1
X           2
Y           3
Y           4

表B:

CONTACT_ID    TYPE    PHONE
----------    ----    -----
1             H       21
1             C
1             W       44
2             H       78
2             C       92
2             W       11

期望的结果:

STUDENT_ID     CONTACT_ID   TYPE   PHONE
----------     ----------   ----   -----
X              1            H      21
X              2            C      92
Y              3
Y              4

这是我的查询,它将与所有电话匹配进行连接(减去我所有疯狂的尝试来获得我想要的东西)。

SELECT *
FROM Table TableA T1
LEFT OUTER JOIN TableB T2 ON T1.CONTACT_ID = T2.CONTACT_ID

非常感谢所有帮助!

根据 Stefan Onofrei 的解决方案编辑的代码:
(导致一些重复条目)

SELECT
    T1.STUDENT_ID,
    T1.CONTACT_ID,
    T2.PHONE_TYPE,
    T3.PHONE
FROM REG_STU_CONTACT T1
INNER JOIN 
    (SELECT MIN(PHONE_TYPE) AS PHONE_TYPE, CONTACT_ID 
    FROM REG_CONTACT_PHONE
    WHERE PHONE IS NOT NULL
    GROUP BY CONTACT_ID) T2 ON T1.CONTACT_ID = T2.CONTACT_ID
INNER JOIN REG_CONTACT_PHONE T3 ON T2.CONTACT_ID = T3.CONTACT_ID AND T2.PHONE_TYPE = T3.PHONE_TYPE
ORDER BY T1.STUDENT_ID

【问题讨论】:

  • 您使用的是哪个数据库? MySQL?微软 SQL 服务器?甲骨文?每个都提供了不同的函数来处理这个需求。

标签: sql sql-server-2005 join outer-join


【解决方案1】:
Select A.STUDENT_ID     A.CONTACT_ID   B.TYPE   c.PHONE 
from TableA A
inner join 
    (select MIN(type ) as type, Contact_ID 
    from Tableb
    where phone is not null
    group by contactid) B
on A.contactid = b.contactid
inner join Tableb C 
on B.contactid = c.conatctid and b.type = c.type

【讨论】:

  • 谢谢!就每个联系人只提供一个电话号码而言,这很有效,但是,它似乎导致了随机重复,其中 STUDENT_ID、CONTACT_ID、PHONE_TYPE 和 PHONE 都相同。这可能是我如何调整上述查询以适应我们的实际环境的结果。你介意看看我的查询,看看我是否有错误地更改了某些内容吗?
  • 你可以试试吗? select * from tbl (select T1.STUDENT_ID, T1.CONTACT_ID, T2.PHONE_TYPE, T2.PHONE , row_number() over (partition by T1.contactid order by T2.PHONE_TYPE) as rowno FROM REG_STU_CONTACT T1 INNER JOIN EG_CONTACT_PHONE T2 on t1。 contactid = t2.contactid WHERE PHONE IS NOT NULL ) tbl where tbl.rowno = 1
  • 对不起,有一个错误这应该工作 select * from (select T1.STUDENT_ID, T1.CONTACT_ID, T2.PHONE_TYPE, T2.PHONE , row_number() over (partition by T1.contactid order by T2 .PHONE_TYPE) as rowno FROM REG_STU_CONTACT T1 INNER JOIN EG_CONTACT_PHONE T2 on t1.contactid = t2.contactid WHERE PHONE IS NOT NULL ) tbl where tbl.rowno = 1
猜你喜欢
  • 2015-03-04
  • 2010-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-01
  • 2022-06-18
  • 1970-01-01
相关资源
最近更新 更多