Sql server 嵌套SQL语句

Sql server 嵌套SQL语句,sql-server,tsql,sql-server-2000,nested-queries,Sql Server,Tsql,Sql Server 2000,Nested Queries,我有一张个人的桌子,一张联系人的桌子(电子邮件、电话等) 和一个用于保存个人联系人的连接表 我想构造一个查询,在一个记录中获取每个人的电子邮件、电话、po 因此,我将有4列结果集用户名,电话,电子邮件,采购订单 当我使用SQLServer2000时,XML不是一个选项 如果您能帮助我们实现这一目标,我们将不胜感激。您未能提供有关专栏的任何有用细节,因此我不得不猜测,但我认为您正在寻找类似的信息 WITH Persons(PersonId, UserName) AS ( SELECT 1, 'Bo

我有一张个人的桌子,一张联系人的桌子(电子邮件、电话等) 和一个用于保存个人联系人的连接表

我想构造一个查询,在一个记录中获取每个人的电子邮件、电话、po

因此,我将有4列结果集用户名,电话,电子邮件,采购订单

当我使用SQLServer2000时,XML不是一个选项


如果您能帮助我们实现这一目标,我们将不胜感激。

您未能提供有关专栏的任何有用细节,因此我不得不猜测,但我认为您正在寻找类似的信息

WITH Persons(PersonId, UserName) AS
(
SELECT 1, 'Bob' UNION ALL
SELECT 2, 'Bill'
), ContactTypes(ContactTypeId, Name) AS
(
SELECT 1, 'Tel' UNION ALL
SELECT 2, 'Email' UNION ALL
SELECT 3, 'PO'
),PersonContacts(PersonId, ContactTypeId, Value) As
(
SELECT 1,1,CAST('(01223) 123456' AS VARCHAR(50)) UNION ALL
SELECT 1,2,CAST('bob@example.com' AS VARCHAR(50)) UNION ALL
SELECT 1,3,CAST('1 Acacia Avenue' AS VARCHAR(50)) UNION ALL
SELECT 2,1,CAST('(01223) 654321' AS VARCHAR(50)) UNION ALL
SELECT 2,2,CAST('bill@example.com' AS VARCHAR(50)) 
)

/*The above Common Table Expressions are just for demo purposes and so you 
can see the assumptions. They will not work on SQL Server 2000. You just need 
the below.*/
SELECT P.UserName, 
       /*I've just used the Ids rather than bothering to join on ContactTypes*/
       MAX(CASE WHEN C.ContactTypeId = 1 then C.Value END) Tel,
       MAX(CASE WHEN C.ContactTypeId = 2 then C.Value END) Email,
       MAX(CASE WHEN C.ContactTypeId = 3 then C.Value END) PO
FROM Persons P
LEFT JOIN PersonContacts C ON C.PersonId = P.PersonId
GROUP BY P.PersonId,P.UserName
返回

UserName Tel                 Email               PO
-------- ------------------- ------------------- ------------------
Bob      (01223) 123456      bob@example.com     1 Acacia Avenue
Bill     (01223) 654321      bill@example.com    NULL

您没有提供任何关于专栏的有用细节,所以我不得不猜测,但我认为您正在寻找类似的内容

WITH Persons(PersonId, UserName) AS
(
SELECT 1, 'Bob' UNION ALL
SELECT 2, 'Bill'
), ContactTypes(ContactTypeId, Name) AS
(
SELECT 1, 'Tel' UNION ALL
SELECT 2, 'Email' UNION ALL
SELECT 3, 'PO'
),PersonContacts(PersonId, ContactTypeId, Value) As
(
SELECT 1,1,CAST('(01223) 123456' AS VARCHAR(50)) UNION ALL
SELECT 1,2,CAST('bob@example.com' AS VARCHAR(50)) UNION ALL
SELECT 1,3,CAST('1 Acacia Avenue' AS VARCHAR(50)) UNION ALL
SELECT 2,1,CAST('(01223) 654321' AS VARCHAR(50)) UNION ALL
SELECT 2,2,CAST('bill@example.com' AS VARCHAR(50)) 
)

/*The above Common Table Expressions are just for demo purposes and so you 
can see the assumptions. They will not work on SQL Server 2000. You just need 
the below.*/
SELECT P.UserName, 
       /*I've just used the Ids rather than bothering to join on ContactTypes*/
       MAX(CASE WHEN C.ContactTypeId = 1 then C.Value END) Tel,
       MAX(CASE WHEN C.ContactTypeId = 2 then C.Value END) Email,
       MAX(CASE WHEN C.ContactTypeId = 3 then C.Value END) PO
FROM Persons P
LEFT JOIN PersonContacts C ON C.PersonId = P.PersonId
GROUP BY P.PersonId,P.UserName
返回

UserName Tel                 Email               PO
-------- ------------------- ------------------- ------------------
Bob      (01223) 123456      bob@example.com     1 Acacia Avenue
Bill     (01223) 654321      bill@example.com    NULL
我想你想要这个:

SELECT p.username, email.value as email, tel.value as tel, po.value as po
FROM persons p
LEFT JOIN contacts as email ON contacts.person_id = person.id
LEFT JOIN contacts as tel ON contacts.person_id = person.id
LEFT JOIN contacts as po ON contacts.person_id = person.id
WHERE email.type = 'email'
AND tel.type = 'tel'
AND po.type = 'po'
因此,您基本上会在contacts表上加入3次,因为contacts表包含3种不同形式的contacts。这是一种多态方法,不能很好地映射到SQL

此查询的结果应类似于:

username | email           | tel       | po
John     | john@john.com   | 012364342 | 1234AA
Sarah    | sarah@sarah.com | NULL      | NULL
我认为martin的解决方案也会起作用,但我对CASE-WHEN-THEN-END不太满意

我认为您希望这样:

SELECT p.username, email.value as email, tel.value as tel, po.value as po
FROM persons p
LEFT JOIN contacts as email ON contacts.person_id = person.id
LEFT JOIN contacts as tel ON contacts.person_id = person.id
LEFT JOIN contacts as po ON contacts.person_id = person.id
WHERE email.type = 'email'
AND tel.type = 'tel'
AND po.type = 'po'
因此,您基本上会在contacts表上加入3次,因为contacts表包含3种不同形式的contacts。这是一种多态方法,不能很好地映射到SQL

此查询的结果应类似于:

username | email           | tel       | po
John     | john@john.com   | 012364342 | 1234AA
Sarah    | sarah@sarah.com | NULL      | NULL

我认为martin的解决方案也会起作用,但我不太喜欢CASE-WHEN-THEN-END

我们必须对您的模式进行猜测,因为您没有在问题的初始版本中向我们提供关键信息:

假设模式
  • 表:人员-用户名(主键)
  • 表:联系人-联系人类型(“电话”、“电子邮件”、“PO”)、联系人信息、联系人ID(主键)、
  • 表:Junction-用户名,ContactID-组合上的PK,每列上的FK
可能的疑问
请注意,为了使查询正常工作,应该强制执行一些复杂的约束。主要的一点是,给定的人要么有零个或一个电子邮件地址,要么有零个或一个电话号码,要么有零个或一个PO(这是邮局地址吗?)。如果有人有以上任何一个条目,您根本不会告诉我们什么可能是合适的输出。而且约束很复杂,因为最简单的版本需要对用户名和联系人类型的组合进行唯一约束,但是这些列并没有存储在任何一个表中。

我们必须猜测您的模式,因为您没有在问题的初始版本中向我们提供关键信息:

假设模式
  • 表:人员-用户名(主键)
  • 表:联系人-联系人类型(“电话”、“电子邮件”、“PO”)、联系人信息、联系人ID(主键)、
  • 表:Junction-用户名,ContactID-组合上的PK,每列上的FK
可能的疑问
请注意,为了使查询正常工作,应该强制执行一些复杂的约束。主要的一点是,给定的人要么有零个或一个电子邮件地址,要么有零个或一个电话号码,要么有零个或一个PO(这是邮局地址吗?)。如果有人有以上任何一个条目,您根本不会告诉我们什么可能是合适的输出。而且约束很复杂,因为最简单的版本需要对用户名和联系人类型的组合进行唯一约束,但是这些列并没有存储在任何一个表中。

您需要为这三个表中的每一个提供更多的模式-精确的表名也会有帮助。您需要为这三个表中的每一个提供更多的模式-精确的表名也会有帮助。@Frits-不,您不会这样做。
groupby
负责这一点。这是一种相当标准的
PIVOT
/
交叉制表技术。效果很好,谢谢。下面的答案也是正确的,但是忽略了空联系人。@Frits-不,你不会这样做。
groupby
负责这一点。这是一种相当标准的
PIVOT
/
交叉表
技术。工作正常,谢谢。下面的答案也是正确的,但忽略了空触点。连接表适合此项的位置?连接表适合此项的位置?