T-sql如何在两个其他行之间获取所有行

时间:2012-01-19 12:49:28

标签: sql tsql

假设我有下表:

Table: Score
field: ID: uniqueidentifier
field: Departmentid: int
field: Score: float
field: EnteredOn: DateTime

如何设计一个查询,该查询给出了部门115和部门119中的条目之间的所有分数?

澄清:如果我有以下记录:

Id, departmentid, score
<some guid>, 115, 1
<some guid>, 100, 2
<some guid>, 119, 3
<some guid>, 115, 2
<some guid>, 102, 1
<some guid>, 119, 4
<some guid>, 115, 2
<some guid>, 100, 4
<some guid>, 120, 4

查询需要检索以下记录:

<some guid>, 100, 2
<some guid>, 102, 1

因为它们在115到119条记录之间。

默认情况下,记录将在EntereOn上排序。

3 个答案:

答案 0 :(得分:3)

它不漂亮,但适用于您的样本数据。

declare @Score table
(
  ID int identity primary key,
  DepartmentID int,
  Score int,
  EnteredOn int
)

insert into @Score values
(115, 1, 1),
(100, 2, 2),
(119, 3, 3),
(115, 2, 4),
(102, 1, 5),
(119, 4, 6),
(115, 2, 7),
(100, 4, 8),
(120, 4, 9)

;with C1 as
(
  select *,
         row_number() over(order by EnteredOn) as rn
  from @Score
), C2 as
(
  select rn,
         row_number() over(order by EnteredOn) as rn2
  from C1
  where DepartmentID = 115
), C3 as
(
  select rn,
         row_number() over(order by EnteredOn) as rn2
  from C1
  where DepartmentID = 119 and rn > (select min(rn) from C2)
), C4 as
(
  select C2.rn as FromRn,
         C3.rn as ToRn
  from C2 
    inner join C3
      on C2.rn2 = C3.rn2
)
select C1.ID, C1.DepartmentID, C1.Score
from C1
  inner join C4
    on C1.rn > C4.FromRn and
       C1.rn < C4.ToRn

答案 1 :(得分:2)

我想避免相关的子查询,但需要115到119之间的多个记录,我认为这是必要的。这是MarkBanister的回答的替代方法(使用一个相关的子查询,而不是两个,但有三个连接而不是两个)。

我没有测试哪种表现更好。

SELECT
  data_between.*
FROM
  Score      AS data_115
INNER JOIN
  Score      AS data_119
    ON data_119.EnteredOn = (SELECT MIN(EnteredOn) FROM Score WHERE DepartmentId IN (115, 119) AND EnteredOn > data_115.EnteredOn)
INNER JOIN
  Score      AS data_between
    ON  data_between.EnteredOn > data_115.EnteredOn
    AND data_between.EnteredOn < data_119.EnteredOn
WHERE
    data_115.DepartmentId = 115
AND data_119.DepartmentId = 119

答案 2 :(得分:1)

尝试:

select m.*
from MyTable m
join (select ms.EnteredOn StartDate,
             (select min(me.EnteredOn) 
              from MyTable me 
              where me.Departmentid = 119 and 
                    me.EnteredOn > ms.EnteredOn) EndDate
      from MyTable ms
      where ms.Departmentid = 115) mr
on m.EnteredOn > mr.StartDate and m.EnteredOn < mr.EndDate
where not exists
(select null
 from MyTable mn 
 where mn.Departmentid = 115 and 
       mn.EnteredOn > mr.StartDate and 
       mn.EnteredOn < mr.EndDate)