sql-server-2008 - 如何在 SQL 中选择行作为 View 的列?

标签 sql-server-2008 t-sql

假设我有 3 个表:AnimalCareTakerApppointment。架构,包含一些数据,如下所示:

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

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

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

我尝试使用子查询,如下所示:

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子句上进行第二级选择,以从top 1中排除id(因为不确定如何获取第二行),就像在排除第一个之后选择top 1行号;其中第一行 id 是(选择顶部 1) 情况。

无论如何,这看起来并不是一个好方法。

请问如何获得所需的输出?

最佳答案

您可以使用以下方式获取行中的所有信息:

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;

关于sql-server-2008 - 如何在 SQL 中选择行作为 View 的列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36792764/

相关文章:

sql - sp_send_dbmail : FROM_ADDRESS

SQL Server 查询以查找成员注册的年数

sql-server-2008 - ColdFusion 查询连接

sql - 如何在 SQL Server 中查询此输出

database - 尝试在 Linq 中执行子查询...遇到问题!

sql - 使用一个 SQL 语句的结果在另一语句中进行计数

java - 如何将表值参数从java传递到sql server存储过程?

c# - TSQL 性能与 @@Error 和它们可以被替换吗?

sql-server - 抛出错误的 T-SQL 函数

sql - 使用 Union 和 Order By 不会出现重复项