我有一张这样的表:
EMP:
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7934 MILLER CLERK 7782 01/23/1982 1300 - 10
7369 SMITH CLERK 7902 12/17/1980 800 - 20
7521 WARD SALESMAN 7698 02/22/1981 1250 500 30
7654 MARTIN SALESMAN 7698 09/28/1981 1250 1400 30
7698 BLAKE MANAGER 7839 05/01/1981 2850 - 30
7782 CLARK MANAGER 7839 06/09/1981 2450 - 10
7839 KING PRESIDENT - 11/17/1981 5000 - 10
7844 TURNER SALESMAN 7698 09/08/1981 1500 - 30
7499 ALLEN SALESMAN 7698 02/20/1981 1600 300 30
7566 JONES MANAGER 7839 04/02/1981 2975 - 20
7788 SCOTT ANALYST 7566 12/09/1982 3000 - 20
7876 ADAMS CLERK 7788 01/12/1983 1100 - 20
7900 JAMES CLERK 7698 12/03/1981 950 - 30
7902 FORD ANALYST 7566 12/03/1981 3000 - 20
如果在该月的最后一个星期五支付任何月份的15日或之前雇用的Emp,那么在15日之后雇用的人将在下个月的第一个星期五付款。打印一份emps列表及其雇用日期和支付日期。
在oracle中我们可以通过简单的查询实现这一点。任何人都可以建议我使用简单的SQL Server查询来显示所需的结果。
以下是我在SQL server中尝试过的代码,
SELECT *,CASE WHEN DATEPART(DD,HIREDATE)<=15
THEN (CASE WHEN DATENAME(WEEKDAY,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))),DATEADD(mm,1,HIREDATE))))='MONDAY'
THEN DATEADD(DD,-4,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))),DATEADD(mm,1,HIREDATE))))
WHEN DATENAME(WEEKDAY,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))),DATEADD(mm,1,HIREDATE))))='TUESDAY'
THEN DATEADD(DD,-3,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))),DATEADD(mm,1,HIREDATE))))
WHEN DATENAME(WEEKDAY,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))),DATEADD(mm,1,HIREDATE))))='WEDNESDAY'
THEN DATEADD(DD,-5,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))),DATEADD(mm,1,HIREDATE))))
WHEN DATENAME(WEEKDAY,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))),DATEADD(mm,1,HIREDATE))))='THURSDAY'
THEN DATEADD(DD,-6,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))),DATEADD(mm,1,HIREDATE))))
WHEN DATENAME(WEEKDAY,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))),DATEADD(mm,1,HIREDATE))))='FRIDAY'
THEN DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))),DATEADD(mm,1,HIREDATE))
WHEN DATENAME(WEEKDAY,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))),DATEADD(mm,1,HIREDATE))))='SATURDAY'
THEN DATEADD(DD,-1,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))),DATEADD(mm,1,HIREDATE))))
WHEN DATENAME(WEEKDAY,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))),DATEADD(mm,1,HIREDATE))))='SUNDAY'
THEN DATEADD(DD,-2,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))),DATEADD(mm,1,HIREDATE))))
END)
ELSE CASE
WHEN DATENAME(WEEKDAY,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))-1),DATEADD(mm,1,HIREDATE))))='MONDAY'
THEN DATEADD(DD,2,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))-1),DATEADD(mm,1,HIREDATE))))
WHEN DATENAME(WEEKDAY,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))-1),DATEADD(mm,1,HIREDATE))))='TUESDAY'
THEN DATEADD(DD,4,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))-1),DATEADD(mm,1,HIREDATE))))
WHEN DATENAME(WEEKDAY,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))-1),DATEADD(mm,1,HIREDATE))))='WEDNESDAY'
THEN DATEADD(DD,3,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))-1),DATEADD(mm,1,HIREDATE))))
WHEN DATENAME(WEEKDAY,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))-1),DATEADD(mm,1,HIREDATE))))='THURSDAY'
THEN DATEADD(DD,1,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))-1),DATEADD(mm,1,HIREDATE))))
WHEN DATENAME(WEEKDAY,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))-1),DATEADD(mm,1,HIREDATE))))='FRIDAY'
THEN DATEADD(DD,0,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))-1),DATEADD(mm,1,HIREDATE))))
WHEN DATENAME(WEEKDAY,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))-1),DATEADD(mm,1,HIREDATE))))='SATURDAY'
THEN DATEADD(DD,6,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))-1),DATEADD(mm,1,HIREDATE))))
WHEN DATENAME(WEEKDAY,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))-1),DATEADD(mm,1,HIREDATE))))='SUNDAY'
THEN DATEADD(DD,5,(DATEADD(dd,-(DAY(DATEADD(mm,1,HIREDATE))-1),DATEADD(mm,1,HIREDATE))))
END
END
FROM EMP;
上面的查询正在按预期工作,但我正在寻找一种简单的方法来实现这一点..... :)
答案 0 :(得分:0)
不知道你想要的结果,这应该足以让你前进。 CASE和DAY TSQL语句将帮助您实现目标。
SELECT
[EmpNo],
[EName],
[HireDate],
CASE
WHEN DAY([HireDate]) <= 15 THEN 'Last Friday'
ELSE 'First Friday'
END AS 'PayDate'
FROM EMP
答案 1 :(得分:0)
这不是你在SQL Server中可以做的事情。如果您确信疯了,请查看使用各种dateadd
,datediff
和%
操作的this example。
稍微好一点的选择是像C#这样的客户端语言,请参阅this SO answer。还是在理智的另一面。
在一天结束时,在Oracle中完成工资核算更容易。您可以使用next_day()
:
select next_day(trunc(sysdate,'MM'), 'FRIDAY') as first_friday
, next_day(last_day(sysdate)-7, 'FRIDAY') as last_friday
from dual
这仍然不是那么容易,但比你在T-SQL中做的任何事情都容易。
答案 2 :(得分:0)
创建功能
CREATE FUNCTION fn_FirstLastFriday(@Year INT)
RETURNS TABLE
AS
-- First and Last Friday
RETURN
(select min(dates) as [First Friday], max(dates) as [Last Friday] from
(
select dateadd(day,number-1,DATEADD(year,@year-1900,0))
as dates from master..spt_values
where type='p' and number between 1 and
DATEDIFF(day,DATEADD(year,@year-1900,0),DATEADD(year,@year-1900+1,0))
) as t
where DATENAME(weekday,dates)='friday'
group by DATEADD(month,datediff(month,0,dates),0))
测试表
DECLARE @EMP TABLE (EMPNO INT,ENAME VARCHAR(20),JOB VARCHAR(20)
,MGR INT, HIREDATE DATE, SAL INT,COMM INT, DEPTNO INT)
INSERT INTO @EMP
VALUES
(7934,'MILLER','CLERK',7782,'01/23/1982',1300, NULL,10),
(7369,'SMITH','CLERK',7902,'12/17/1980',800,NULL,20),
(7521,'WARD','SALESMAN',7698,'02/22/1981',1250,500,30)
<强>查询强>
SELECT *, CASE WHEN DAY(E.HIREDATE) >= 1 AND DAY(E.HIREDATE) <= 15 THEN T.[Last Friday]
ELSE T.[First Friday] END AS Friday
FROM @EMP E
CROSS APPLY
dbo.fn_FirstLastFriday(YEAR(E.HIREDATE)) T
结果集
╔═══════╦════════╦═══════╦══════╦════════════╦══════╦══════╦════════╦═════════════════════════╦═════════════════════════╦═════════════════════════╗
║ EMPNO ║ ENAME ║ JOB ║ MGR ║ HIREDATE ║ SAL ║ COMM ║ DEPTNO ║ First Friday ║ Last Friday ║ Friday ║
╠═══════╬════════╬═══════╬══════╬════════════╬══════╬══════╬════════╬═════════════════════════╬═════════════════════════╬═════════════════════════╣
║ 7934 ║ MILLER ║ CLERK ║ 7782 ║ 1982-01-23 ║ 1300 ║ NULL ║ 10 ║ 1982-01-01 00:00:00.000 ║ 1982-01-29 00:00:00.000 ║ 1982-01-01 00:00:00.000 ║
║ 7934 ║ MILLER ║ CLERK ║ 7782 ║ 1982-01-23 ║ 1300 ║ NULL ║ 10 ║ 1982-02-05 00:00:00.000 ║ 1982-02-26 00:00:00.000 ║ 1982-02-05 00:00:00.000 ║
║ 7934 ║ MILLER ║ CLERK ║ 7782 ║ 1982-01-23 ║ 1300 ║ NULL ║ 10 ║ 1982-03-05 00:00:00.000 ║ 1982-03-26 00:00:00.000 ║ 1982-03-05 00:00:00.000 ║
║ 7934 ║ MILLER ║ CLERK ║ 7782 ║ 1982-01-23 ║ 1300 ║ NULL ║ 10 ║ 1982-04-02 00:00:00.000 ║ 1982-04-30 00:00:00.000 ║ 1982-04-02 00:00:00.000 ║
║ 7934 ║ MILLER ║ CLERK ║ 7782 ║ 1982-01-23 ║ 1300 ║ NULL ║ 10 ║ 1982-05-07 00:00:00.000 ║ 1982-05-28 00:00:00.000 ║ 1982-05-07 00:00:00.000 ║
║ 7934 ║ MILLER ║ CLERK ║ 7782 ║ 1982-01-23 ║ 1300 ║ NULL ║ 10 ║ 1982-06-04 00:00:00.000 ║ 1982-06-25 00:00:00.000 ║ 1982-06-04 00:00:00.000 ║
╚═══════╩════════╩═══════╩══════╩════════════╩══════╩══════╩════════╩═════════════════════════╩═════════════════════════╩═════════════════════════╝
注意强>
我已经添加了第一个和最后一个星期五在我的答案中只有Demo pupose,但您可以从答案中排除这些列 使用我使用
CASE
语句的最后一列[星期五]。
答案 3 :(得分:0)
SELECT ENAME, HIREDATE,
CASE WHEN TO_CHAR(HIREDATE,'DD')<=15
THEN NEXT_DAY(LAST_DAY(HIREDATE)-7,'FRI')
ELSE NEXT_DAY(LAST_DAY(ADD_months(HIREDATE,1))-7,'FRI')
END "payDATE"
FROM EMP;