我正在使用SQL Server 2008.我有两个表:
客户
CREATE TABLE Clients
(
Id int primary key,
Name varchar(20),
ParentId int
);
INSERT INTO Clients(Id, Name, ParentId) VALUES (1, 'A', 1);
INSERT INTO Clients(Id, Name, ParentId) VALUES (2, 'B', 2);
INSERT INTO Clients(Id, Name, ParentId) VALUES (3, 'AA', 1);
INSERT INTO Clients(Id, Name, ParentId) VALUES (4, 'BB', 2);
INSERT INTO Clients(Id, Name, ParentId) VALUES (5, 'C', 1);
此表包含所有客户的信息,其中一些有父公司/客户,ParentId显示。如果它与Id匹配,则意味着这些客户端是层次结构中的顶级公司。
联系人
CREATE TABLE Contacts
(
Id int primary key,
Name varchar(20),
Email varchar(20),
ClientId int
);
INSERT INTO Contacts(Id, Name, Email, ClientId) VALUES (1, 'Bob', 'Bob@A.com', 1);
INSERT INTO Contacts(Id, Name, Email, ClientId) VALUES (2, 'John', 'John@A.com', 1);
INSERT INTO Contacts(Id, Name, Email, ClientId) VALUES (3, 'Charlie', 'Charlie@B.com', 2);
INSERT INTO Contacts(Id, Name, Email, ClientId) VALUES (4, 'Peter', 'Peter@AA.com', 3);
INSERT INTO Contacts(Id, Name, Email, ClientId) VALUES (5, 'Chris', 'Chris@AA.com', 3);
INSERT INTO Contacts(Id, Name, Email, ClientId) VALUES (6, 'Neil', 'Neil@BB.com', 4);
INSERT INTO Contacts(Id, Name, Email, ClientId) VALUES (7, 'Grant', 'Grant@C.com', 5);
INSERT INTO Contacts(Id, Name, Email, ClientId) VALUES (8, 'Cher', 'Cher@C.com', 5);
此表包含特定客户端的所有联系人(ClientId
显示它)。
我需要有一个列表,其中包含客户和特定客户的所有联系人以及他母公司的所有联系人。
例如
ClientName | ContactName | ContactEmail
AA | |
| Bob | Bob@A.com
| John | John@A.com
| Peter | Peter@AA.com
| Chris | Chris@AA.com
C | |
| Grant | Grant@C.com
| Cher | Cher@C.com
我设法编写了一个SQL查询,它只为一个客户端提供结果,但我希望它返回多个客户端。如上所示向客户(第3和第5)及其联系人显示。
SELECT
C.Name, ' ', ' '
FROM
Clients C
WHERE
C.Id = 3
UNION ALL
SELECT
' ', Co.Name, Co.Email
FROM
Contacts Co
WHERE
ClientId = 3 OR (ClientId = (SELECT ParentId FROM Clients WHERE Id = 3))
答案 0 :(得分:1)
没有SQL格式。
select
Cli.Name,
Co.Name,
Co.Email
from Clients Cli
left join Contacts Co on
Co.ClientId in(Cli.Id,Cli.ParentId)
order by
1,2
使用Formatting ..你真的应该在SQL之外进行格式化。但这是一种方法
select
CASE WHEN cls <> 1 THEN '' ELSE CLI_NAME END CLIENT_NAME,
CO_NAME CONTACT_NAME,
CO_EMAIL CONTACT_EMAIL
from (
select
ROW_NUMBER() OVER (
PARTITION BY
T.CLI_NAME
ORDER BY
T.CO_NAME
) cls,
CLI_NAME,
CO_NAME,
CO_EMAIL
from (
select
Cli.Name CLI_NAME,
'' CO_NAME,
'' CO_EMAIL
from Clients Cli
WHERE
Cli.id in (3,5)
UNION ALL
select
Cli.Name,
Co.Name,
Co.Email
from Clients Cli
left join Contacts Co on
Co.ClientId in(Cli.Id,Cli.ParentId)
WHERE
Cli.id in (3,5)
) T
) T
order by
CLI_NAME,
CO_NAME
答案 1 :(得分:0)
如果客户只有一家母公司并且这不是递归的,那么您也可以使用UNION获取母公司数据。我会在报告工具中根据需要格式化数据,而不是尝试在SQL中执行此操作。
SELECT
Clients.Name AS ClientName,
Contacts.Name AS ContactName,
Contacts.Email AS ContactEmail
FROM
Clients
JOIN
Contacts
ON
Clients.Id = Contacts.ClientId
UNION
SELECT
Clients.Name AS ClientName,
Contacts.Name AS ContactName,
Contacts.Email AS ContactEmail
FROM
Clients
JOIN
Contacts
ON
Clients.ParentId = Contacts.ClientId
ORDER BY
ClientName,
ContactName
答案 2 :(得分:0)
这是一个通用解决方案(没有格式化),允许孩子拥有子/层次结构深度&gt; 1
WITH parentcte (id,parentid,name)
AS (SELECT c1.id,
c1.parentid,name
FROM clients c1
WHERE c1.id=3 -- you can remove the where clause if you want list of all clients
UNION ALL
SELECT
c.id,c.parentid,parentcte.name
FROM parentcte
JOIN clients c
ON
c.id=parentcte.parentid where c.id != c.parentid)
select distinct p.name,con.name,email from parentcte p
join contacts con on con.ClientId=p.id or con.clientid=p.parentid