SQL语句 - 基于日期的连接

时间:2015-09-21 14:17:30

标签: sql-server date

我需要根据日期编写一个连接两个表的语句。

表1包含时间记录条目。

+----+-----------+--------+---------------+  
| ID | Date      | UserID | DESC          |  
+----+-----------+--------+---------------+  
| 1  | 1.10.2010 | 5      | did some work |  
| 2  | 1.10.2011 | 5      | did more work |  
| 3  | 1.10.2012 | 4      | me too        |  
| 4  | 1.11.2012 | 4      | me too        |  
+----+-----------+--------+---------------+  

表2包含公司中每个用户的位置。 ValidFrom日期是用户被提升或将被提升的日期。

+----+-----------+--------+------------+
| ID | ValidFrom | UserID | Pos        |
+----+-----------+--------+------------+
| 1  | 1.10.2009 | 5      | PM         |
| 2  | 1.5.2010  | 5      | Senior PM  |
| 3  | 1.10.2010 | 4      | Consultant |
+----+-----------+--------+------------+

我需要一个查询,该查询输出一个带有一个添加列的表,该列是用户在创建条目时的位置。 (日期栏) 所有日期文件都是日期类型。

我希望有人可以提供帮助。我尝试了很多,但没有让它发挥作用。

4 个答案:

答案 0 :(得分:4)

使用where子句中的子选择来尝试:

SQL Fiddle

MS SQL Server 2008架构设置

CREATE TABLE TimeRecord
(
  ID INT,
  [Date] Date,
  UserID INT,
  Description VARCHAR(50)
)

INSERT INTO TimeRecord
VALUES (1,'2010-01-10',5,'did some work'),
        (2, '2011-01-10',5,'did more work'),
        (3, '2012-01-10', 4, 'me too'),
        (4, '2012-11-01',4,'me too') 

CREATE TABLE UserPosition
(
  ID Int,
  ValidFrom Date,
  UserId INT,
  Pos VARCHAR(50)
)
INSERT INTO UserPosition
VALUES (1, '2009-01-10', 5, 'PM'),
      (2, '2010-05-01', 5, 'Senior PM'),
      (3, '2010-01-10', 4, 'Consultant ')

查询1

SELECT TR.ID,
       TR.[Date],
       TR.UserId,
       TR.Description,
       UP.Pos
FROM TimeRecord TR
INNER JOIN UserPosition UP
  ON UP.UserId = TR.UserId 
WHERE UP.ValidFrom = (SELECT MAX(ValidFrom) 
                      FROM UserPosition UP2 
                      WHERE UP2.UserId = UP.UserID AND
                            UP2.ValidFrom <= TR.[Date])

<强> Results

| ID |       Date | UserId |   Description |         Pos |
|----|------------|--------|---------------|-------------|
|  1 | 2010-01-10 |      5 | did some work |          PM |
|  2 | 2011-01-10 |      5 | did more work |   Senior PM |
|  3 | 2012-01-10 |      4 |        me too | Consultant  |
|  4 | 2012-11-01 |      4 |        me too | Consultant  |

答案 1 :(得分:2)

您可以使用OUTER APPLY执行此操作:

SELECT ID, [Date], UserID, [DESC], x.Pos
FROM table1 AS t1
OUTER APPLY (
  SELECT TOP 1 Pos
  FROM table2 AS t2
  WHERE t2.UserID = t1.UserID AND t2.ValidFrom <= t1.[Date]
  ORDER BY t2.ValidFrom DESC) AS x(Pos)

对于table1 OUTER APPLY操作的每一行,都会抓取同一用户的所有table2行,其ValidFrom日期早于[Date]或与OUTER APPLY相同}。这些行按降序排序,最后返回最新的

注意:如果NULL子查询未找到匹配项,则返回table2值,表示table1import SimpleHTTPServer import SocketServer Handler = SimpleHTTPServer.SimpleHTTPRequestHandler port = 8000 while True: try: httpd = SocketServer.TCPServer(('', port), Handler) print 'Serving on port', port httpd.serve_forever() except SocketServer.socket.error as exc: if exc.args[0] != 48: raise print 'Port', port, 'already in use' port += 1 else: break 中没有有效位置用于#!/usr/bin/env bash MIN_PORT=${1:-1025} MAX_PORT=${2:-65535} (netstat -atn | awk '{printf "%s\n%s\n", $4, $4}' | grep -oE '[0-9]*$'; seq "$MIN_PORT" "$MAX_PORT") | sort -R | head -n 1 中的相应记录1}}。

Demo here

答案 2 :(得分:1)

这可以通过使用秩函数和子查询来实现。我用一些样本数据测试了它。

   select sub.ID,sub.Date,sub.UserID,sub.Description,sub.Position 
from(
    select rank() over(partition by t1.userID order by t2.validfrom desc) 
    as 'rank', t1.ID as'ID',t1.Date as'Date',t1.UserID as'UserID',t1.Descr   
    as'Description',t2.pos as'Position', t2.validfrom as 'validfrom' 

    from temployee t1 inner join jobs t2 on -- replace join tables with your own table names
    t1.UserID=t2.UserID 
    ) as sub
where rank=1

答案 3 :(得分:0)

此查询可以正常工作

select t1.*,t2.pos from Table1 t1 left outer join Table2 t2 on 
t1.Date=t2.Date and t1.UserID=t2.UserID