SQL将表1上的日期连接到table2上的月份名称

时间:2016-11-11 18:50:38

标签: sql-server

我有一个有销售订单的table1。我需要添加销售人员报告的经理,该经理不在table1上,而是在table2上。一个销售人员可以改变经理,所以如果在1月,他的经理是约翰,而在12月,他的经理是史蒂夫,我希望在1月份出售给经理约翰和12月出售给经理史蒂夫。 table1有一个销售日期。但是table2只有一个字符串,如2015年1月或2015年12月。我如何根据日期获得属于每笔销售的经理名称?

表1

orderID     orderdate     repname
10          2015-01-10     Carlos
25          2015-12-15     Carlos

和表2

Repname    period          manager
Carlos     January 2015    John 
Carlos     December 2015   Steve    <-- he has a new manager in Dec

我希望最终结果是

orderID     orderdate     repname     manager
10          2015-01-10     Carlos     John 
25          2015-12-15     Carlos     Steve

3 个答案:

答案 0 :(得分:0)

以下是给定示例的查询。但是来自@ahmedAbdelqader的问题是有道理的。

SELECT T1.OrderID
    , T1.OrderDate
    , T1.RepName
    , T2.Manager
FROM Table1 T1
INNER JOIN Table2 T2
    ON T1.RepName = T2.RepName 
    AND (T1.OrderDate BETWEEN CONVERT(DATETIME, T2.Period) AND DATEADD(M,1,CONVERT(DATETIME, T2.Period)))

答案 1 :(得分:0)

如果发生管理层更改时,Table2 有记录,您可以使用ROW_NUMBER()

考虑这个测试数据:

create table #table1
(
    orderID int,
    orderdate date,
    repname nvarchar(20)
)
insert #table1 select 10,'1/10/2015','Carlos'
insert #table1 select 11,'1/12/2015','Frank'
insert #table1 select 12,'3/15/2015','Frank'
insert #table1 select 13,'2/1/2015','Carlos'
insert #table1 select 25,'12/15/2015','Carlos'
insert #table1 select 26,'12/31/2015','Frank'
insert #table1 select 77,'1/3/2016','Carlos'

create table #table2
(
    repname nvarchar(20),
    period nvarchar(50),
    manager nvarchar(20)
)

insert #table2 select 'Carlos', 'January 2015', 'John'
insert #table2 select 'Frank', 'January 2015', 'John'
insert #table2 select 'Frank', 'February 2015', 'Jenny'
insert #table2 select 'Carlos', 'December 2015', 'Steve'

此查询返回预期结果:

SELECT orderid, repname, orderdate, manager
FROM (
    SELECT  t1.orderid,
            t1.repname,
            t1.orderdate,
            t2.manager,
            ROW_NUMBER() OVER(PARTITION BY t1.repname, t1.orderdate
                        ORDER BY CONVERT(datetime, t2.Period) DESC) as RowNum
FROM #table1 t1
    INNER JOIN #table2 t2
        ON t1.repname = t2.repname
        AND t1.orderdate >= CONVERT(datetime, t2.Period)

) salespersonmanagers
WHERE RowNum = 1
ORDER BY orderdate

结果

10  Carlos  2015-01-10  John
11  Frank   2015-01-12  John
13  Carlos  2015-02-01  John
12  Frank   2015-03-15  Jenny
25  Carlos  2015-12-15  Steve
26  Frank   2015-12-31  Jenny
77  Carlos  2016-01-03  Steve

内部查询根据代表名称返回所有联接记录,其中订单日期&gt; =期间和经理。如果他们在这段时间内没有经理变更,则会返回最近一次的经理变更,并指定一个行号,其中最近的经理是最低的行号。

外部查询仅返回第1行中的那些(最近的经理更改)。

答案 2 :(得分:0)

也许有另一种方法,但我的如下......

解决此问题的关键

1)在日期列中获取月份名称。 ex: january

2)获取句号列的第一个单词。 ex: january

然后使用Join子句(绝对)

彼此相等

您可以使用系统功能到达键的前半部分:

  

DATENAME(datepart,date)

关键的下半部分使用下一个代码:

Select SUBSTRING(period,1,(CHARINDEX(' ',columnName+ ' ')-1))

<强>演示: -

Create table Table1
(orderID int , orderdate date, repname varchar(30))
go
insert into Table1 values (10,' 2015-01-10','Carlos')
go
insert into Table1 values (20,' 2015-12-10','Carlos')
go

Create table Table2
( repname varchar(30), period varchar(50),  manager varchar(30))
go
insert into Table2 values ('Carlos','January 2015','John')
go
insert into Table2 values ('Carlos','December 2015','Steve')
go

select  orderID,orderdate,a.repname, b.manager
from table1 a, table2 b
where a.repname = b.repname
and DateName( month, orderdate) = SUBSTRING(period,1,(CHARINDEX(' ',period + ' ')-1))

结果: -

enter image description here