多个联接,如果多次出现,则显示一个值

时间:2013-11-20 01:49:56

标签: sql

说我有3张桌子:

表1 t1

id  c1     c2
 1  Jon    Doe
 2  James  SMith
 3  jolly  rancher

表2 t2

id  c1
 1  addr_1
 1  addr_2
 2  addr_1
 2  addr_2
 3  addr_1

表3 t3

id  c1
 1  phone_1
 2  phone_1
 3  phone_1
 3  phone_2

我想要得到的是:

1  Jon    Doe      addr_1  phone_1
1                  addr_2
2  James  SMith    addr_1  phone_1
2                  addr_2
3  jolly  rancher  addr_1  phone_1
3                          phone_2

因此,每个输出都有id,但每个分组只有一次其他字段 - 这可能吗?

1 个答案:

答案 0 :(得分:1)

有可能吗?是。这是理想的吗?并不是的。我必须同意D Stanley的观点,如果可以,最好在app / reporting层处理这样的事情。

但是,如果您真的想在SQL中执行此操作,可以在下面看到我的解决方案或转到SQL fiddle here。此解决方案并不理想,因为它只能处理您提供的示例数据。如果您的数据中至少有2个电话号码,并且给定人员至少有2个地址,则需要修改下面的SQL以处理该情况。我已经将表格和列重命名为更有意义的内容,以便更容易阅读。

create table person(
  id int,
  firstName varchar(20),
  lastName varchar(20)
  )

create table address(
  id int,
  addr varchar(20)
  )

create table phonenumber(
  id int,
  phoneNum varchar(20)
  )

insert person (id, firstName, lastName)select 1, 'jon', 'doe'
insert person (id, firstName, lastName)select 2, 'james', 'smith'
insert person (id, firstName, lastName)select 3, 'jolly', 'rancher'

insert address(id, addr)select 1, 'addr_1'
insert address(id, addr)select 1, 'addr_2'
insert address(id, addr)select 2, 'addr_1'
insert address(id, addr)select 2, 'addr_2'
insert address(id, addr)select 3, 'addr_1'

insert phonenumber(id, phoneNum)select 1, 'phone_1'
insert phonenumber(id, phoneNum)select 2, 'phone_1'
insert phonenumber(id, phoneNum)select 3, 'phone_1'
insert phonenumber(id, phoneNum)select 3, 'phone_2'

CREATE TABLE #results(
  id int,
  firstName varchar(20),
  lastName varchar(20),
  address varchar(20),
  phoneNumber varchar(20)
  )

CREATE TABLE #finalresults(
  id int,
  firstName varchar(20),
  lastName varchar(20),
  address varchar(20),
  phoneNumber varchar(20)
  )

INSERT #results
  (
  id, firstName, lastName, address, phoneNumber
  )
SELECT Person.id, Person.firstName, Person.lastName, address.addr, phonenumber.phoneNum
FROM Person
INNER JOIN address
  ON person.id = address.id
INNER JOIN phonenumber
  ON person.id = phonenumber.id

DECLARE @id int, @firstname varchar(20), @lastname varchar(20),
  @address varchar(20), @phonenumber varchar(20)

DECLARE my_cursor CURSOR
  FOR SELECT * FROM #results
OPEN my_cursor
FETCH NEXT FROM my_cursor INTO @id, @firstname, @lastname, @address, @phonenumber

while @@fetch_status = 0
BEGIN
  IF NOT EXISTS (SELECT 1 FROM #finalresults WHERE id = @id)
  BEGIN
    INSERT #finalresults(id, firstname, lastname, address, phonenumber)
    SELECT @id, @firstname, @lastname, @address, @phonenumber
  END  
  ELSE
  BEGIN
    INSERT #finalresults(id, firstname, lastname, address, phonenumber)
    SELECT distinct @id, '', '',
            CASE WHEN finalAddress.address IS NOT NULL
            THEN ''
            ELSE @address
            END,
            CASE WHEN finalPhoneNumber.phonenumber IS NOT NULL
            THEN ''
            ELSE @phonenumber
            END
    FROM #finalresults
    LEFT OUTER JOIN #finalresults finalAddress
      ON finalAddress.id = @id
      AND finalAddress.address = @address
    LEFT OUTER JOIN #finalresults finalPhoneNumber
      ON finalPhoneNumber.id = @id
      AND finalPhoneNumber.phonenumber = @phonenumber
  END

  FETCH NEXT FROM my_cursor INTO @id, @firstname, @lastname, @address, @phonenumber

END

CLOSE my_cursor
DEALLOCATE my_cursor

SELECT * FROM #finalresults