在SQL联接中 - 一对多根据上下文多次选择一列

时间:2014-11-12 00:07:12

标签: sql sql-server

我有两个表,一个包含记录,一个记录日期时间戳记在执行操作时。例如:

CREATE TABLE MyRecord(
  RecNumber INT IDENTITY(1,1) PRIMARY KEY
  ,TaskDetail NVARCHAR(200)
)

CREATE TABLE MyLOG(
  LogID INT IDENTITY(1,1) PRIMARY KEY
  ,DTStamp DATETIME2(2)
  ,TaskName NVARCHAR(10)
  ,RecNumber
  ,FOREIGN KEY ( RecNumber ) references MyRecord(RecNumber ) 
)

例如,如果我有

|RecNumber|TaskDetail
| 1       | Some Task

|LogID|DTStamp                |TaskName  |RecNumber|
| 1   | 2014-11-11 00:00:00.00|StartTask | 1       |
| 2   | 2014-11-11 00:01:00.00|EndTask   | 1       |

我想要一个返回的查询:

|RecNumber|TaskDetail| Start Time             | End Time              |
| 1       | Some Task| 2014-11-11 00:00:00.00 | 2014-11-11 00:01:00.00|

现在我知道我可以使用嵌套的select语句来获取开始和结束时间。使用连接我可以得到开始时间或结束时间。如何在不使用嵌套SQL的情况下获得两者?或者 - 嵌套的select语句是最好的方法吗?

也许我说这一切都错了。

2 个答案:

答案 0 :(得分:3)

另一种方式是条件聚合:

select r.recnumber,
       r.taskdetail,
       max(case when l.taskname = 'StartTask' then l.dtstamp end) as start_time,
       max(case when l.taskname = 'EndTask' then l.dtstamp end) as end_time
  from myrecord r
  join mylog l
    on r.recnumber = l.recnumber
group by r.recnumber,
         r.taskdetail

答案 1 :(得分:1)

您可以通过各种方式执行此操作。这是一种只使用join的方法,假设每种类型最多只有一个匹配的行:

select r.*, ls.DTStamp as StartTask, le.DTStamp as EndTask
from MyRecord r left join
     MyLog ls
     on r.recNumber = ls.recNumber and ls.TaskName = 'StartTask' left join
     MyLog le
     on r.recNumber = le.recNumber and le.TaskName = 'EndTask;