2016-04-22 53 views
2

假设我有3个表格:AnimalCareTakerApppointment。模式,有这样的一些数据:如何选择行作为TSQL视图的列?

Create Table Animal (Id int identity, Name varchar(25)) 
Create Table CareTaker(Id int identity, Name varchar(50)) 
Create Table Appointments(Id int identity, AnimalId int, CareTakerId int, AppointmentDate DateTime, BookingDate DateTime) 

Insert into Animal(Name) Values('Ghost'), ('Nymeria'), ('Greywind'), ('Summer') 
Insert into CareTaker(Name) Values ('Jon'), ('Arya'), ('Rob'), ('Bran') 

Insert into Appointments(AnimalId, CareTakerId, AppointmentDate, BookingDate) Values 
(1, 1, GETDATE() + 7, GetDate()), -- Ghost cared by Jon 
(1, 2, GETDATE() + 6, GetDate()), -- Ghost cared by Arya 
(4, 3, GETDATE() + 8, GetDate()) -- Summer cared by Rob 

我想为每只动物只选择3个看守者作为列。这样的事情: enter image description here

我不关心其他约会,只是接下来的三个,每个动物。如果没有三个约会,它可以是空白/空白。

我很困惑如何做到这一点。

我与子查询试了一下,像这样:

select Name, 
    -- Care Taker 1 
    (Select Top 1 C.Name 
    From Appointments A 
     Join CareTaker C on C.Id = A.CareTakerId 
    Where A.AppointmentDate > GETDATE() 
     And A.AnimalId = Animal.Id 
    Order By AppointmentDate) As CareTaker1, 
    -- Appointment Date 1 
    (Select Top 1 AppointmentDate 
    From Appointments 
    Where AppointmentDate > GETDATE() 
     And AnimalId = Animal.Id 
    Order By AppointmentDate) As AppointmentDate1 
From Animal 

但对于第二看守政府,我会去第二层选择在where子句从顶部1中排除的ID(因为不知道如何获得第二排),像select top 1 after excluding first row id; where first row id is (select top 1) situtation。

无论如何,这看起来不是一个很好的方法来做到这一点。

我怎样才能得到所需的输出?

回答

2

可以使用得到所有信息行:

select an.name as animal, ct.name as caretaker, a.appointmentdate 
from appointments a join 
    animals an 
    on a.id = an.animalid join 
    caretaker c 
    on a.caretakerid = c.id; 

然后,你基本上要转动此。一种方法使用pivot关键字。另一个条件聚合。我更喜欢后者。无论哪种,你需要一个支点列,这是使用row_number()前提:

select animal, 
     max(case when seqnum = 1 then caretaker end) as caretaker1, 
     max(case when seqnum = 1 then appointmentdate end) as appointmentdate1, 
     max(case when seqnum = 2 then caretaker end) as caretaker2, 
     max(case when seqnum = 2 then appointmentdate end) as appointmentdate2, 
     max(case when seqnum = 3 then caretaker end) as caretaker3, 
     max(case when seqnum = 3 then appointmentdate end) as appointmentdate3 
from (select an.name as animal, ct.name as caretaker, a.appointmentdate, 
      row_number() over (partition by an.id order by a.appointmentdate) as seqnum 
     from appointments a join 
      animals an 
      on a.id = an.animalid join 
      caretaker c 
      on a.caretakerid = c.id 
    ) a 
group by animal; 
+0

你好,谢谢你,我期待到透视表现在..您的查询并不完全做我想做的是:http:// i.imgur.com/jQrcydK.png顶部是我原始帖子的子查询,底部是您的查询 – LocustHorde

+0

@LocustHorde。 。 。不幸的是,我无法建立一个SQL小提琴。但是,这应该是每个动物返回一行,最多三次约会。 –

+0

嗨,是的,SQL小提琴已经打破了我一段时间,我不能建立或加载任何现有的网址。你能解释一下'seqnum'和'row_number()'在做什么?该查询不起作用,我不明白它是如何将行转换为列 – LocustHorde