2014-10-17 15 views
1

我使用SQL Server 2008中我有兩個表:創建SQL查詢,向客戶展示和他們接觸

客戶

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', '[email protected]', 1); 
INSERT INTO Contacts(Id, Name, Email, ClientId) VALUES (2, 'John', '[email protected]', 1); 
INSERT INTO Contacts(Id, Name, Email, ClientId) VALUES (3, 'Charlie', '[email protected]', 2); 
INSERT INTO Contacts(Id, Name, Email, ClientId) VALUES (4, 'Peter', '[email protected]', 3); 
INSERT INTO Contacts(Id, Name, Email, ClientId) VALUES (5, 'Chris', '[email protected]', 3); 
INSERT INTO Contacts(Id, Name, Email, ClientId) VALUES (6, 'Neil', '[email protected]', 4); 
INSERT INTO Contacts(Id, Name, Email, ClientId) VALUES (7, 'Grant', '[email protected]', 5); 
INSERT INTO Contacts(Id, Name, Email, ClientId) VALUES (8, 'Cher', '[email protected]', 5); 

此表包含了所有與特定客戶端觸點(ClientId顯示它)。

我需要一個包含客戶端和特定客戶端的所有聯繫人以及他的母公司的所有聯繫人的列表。

例如

ClientName | ContactName | ContactEmail 
    AA  |    | 
      |  Bob  | [email protected] 
      |  John  | [email protected] 
      |  Peter | [email protected] 
      |  Chris | [email protected] 
    C  |    | 
      |  Grant | [email protected] 
      |  Cher  | [email protected] 

我好不容易寫一個SQL查詢其給出的結果只是一個客戶端,但我希望它返回一個以上的客戶端。向客戶展示(第三和第五)以及他們的聯繫方式。

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

爲什麼你需要的數據有確切的格式? – mxix 2014-10-17 09:24:38

+0

小孩可以有小孩嗎?什麼是層次結構的深度? – Sameer 2014-10-17 09:27:50

+0

因爲這種請求來自用戶:) – 2014-10-17 13:13:43

回答

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 

隨着格式..你真的應該做格外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 
+0

謝謝。這正是我想要的。只是一個問題:在哪裏添加一個子句:哪裏C.id = 3或C.id = 5(選擇第3和第5個客戶端?) – 2014-10-17 13:35:47

+0

@shummis添加where子句 – mxix 2014-10-17 13:42:54

+0

非常感謝! – 2014-10-17 14:10:53

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 
0

這裏是一個通用的解決方案(不帶格式),允許孩子有孩子/分級深度> 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