2016-11-12 102 views
0

我目前使用SQL Server 2016 ...SQL按日期

需要幫助寫一個新的查詢加入。

銷售可能看起來像:

enter image description here

僱員表可能看起來像:

enter image description here

我想從銷售表調用的所有行,並在導師帶字段從僱員表中 - 但是,我需要監督員字段根據employee_table中的date_to和date_from字段進行連接。例如,這是想我的輸出什麼,我的樣子:

enter image description here

的主管人員和銷售代表對準將取決於在銷售表的日期並在該日期落在date_from和DATE_TO字段之間在僱員表中。在這種情況下,自11/4首次銷售在2016年1月1日至2016年6月11日期間 - 當我們在員工表中加入sales_rep_id時,主管將成爲Jim Jones。但是,2016年11月15日發生的拍賣在2016年7月11日至12月31日/ 2999之間進行,這與湯姆·霍爾的監督有關。

任何幫助表示讚賞!

+0

代碼中缺少一個逗號。 – wildplasser

+0

指定您正在使用哪個DBMS –

+0

@EmilHolub SQL Server 2016 – user3067478

回答

2

設置:

create table Sales 
(
    sale_date DATE, 
    sales_rep_name NVARCHAR(100), 
    sales_rep_id INT, 
) 
GO 

insert into Sales VALUES 
    ('20161004', 'Old man', 123), 
    ('20161104', 'Smith, John', 12345), 
    ('20161115', 'Smith, John', 12345) 
GO 

create table Employees 
(
    sales_rep_name NVARCHAR(100), 
    sales_rep_id INT, 
    supervisor NVARCHAR(100), 
    date_from DATE, 
    date_to DATE 
) 
GO 

測試:

INSERT INTO Employees VALUES ('Smith, John', 12345, 'Jones, Jim', '20160101', '20160611'), 
    ('Smith, John', 12345, 'Hall, Tom', '20160711', '99991231') 
GO 

-- gets all sales where INNER JOIN will go 
-- even if LEFT JOIN is used, BETWEEN applied to NULL will rule out some records 
SELECT S.sale_date, E.sales_rep_name, S.sales_rep_name, E.supervisor 
FROM Sales S 
    JOIN Employees E ON S.sales_rep_id = E.sales_rep_id 
     AND S.sale_date BETWEEN E.date_from and E.date_to 


UNION ALL

-- just NULL the columns for the rest of the records 
SELECT S.sale_date, NULL, S.sales_rep_name, NULL 
FROM Sales S 
    WHERE NOT EXISTS (SELECT 1 FROM Employees E WHERE E.sales_rep_id = S.sales_rep_id AND S.sale_date BETWEEN E.date_from and E.date_to) 

GO

+0

只需將'WHERE S.sale_date BETWEEN'更改爲'AND S.sale_date BETWEEN',並且不需要'UNION' :) – dnoeth

1

你的員工表是所謂的Slowly Changing Dimension Type 2,你需要之間的外,作爲附加條件加入:

SELECT * 
FROM SALES AS sal 
LEFT JOIN EMPLOYEES AS emp 
    ON sal.SALES_REP_ID = emp.SALES_REP_ID 
AND sal.DATE BETWEEN emp.DATE_FROM AND emp.DATE_TO 

不要把之間的WHERE,因爲這將結果轉換爲一個內再次加入。

1

我建議LEFT JOIN,這樣你就不會錯過任何銷售。下面是使用它的正確方法:

SELECT s.Date, e.sales_rep_name, s.sales_rep_id, e.supervisor 
FROM sales s LEFT JOIN 
    employees e 
    ON s.sales_rep_id = e.sales_rep_id AND 
     s.date >= e.date_from AND 
     s.date <= e.date_to; 

注意日期條件需要ON子句中去的LEFT JOIN。此外,表別名可以更輕鬆地編寫和讀取查詢。如果銷售沒有匹配,則來自sales的信息將位於employees的列中的NULL值的結果集中。