将Access查询转换为SQL Server查询

时间:2016-03-04 18:56:33

标签: sql-server ms-access

我有一个MS Access查询,我想在SQL Server查询转换,任何帮助将不胜感激。

SELECT
  dbo_Employees.*,
  (SELECT top 1 dbo_attendance.attend_date
    FROM dbo_Attendance
    WHERE dbo_attendance.ID_Employee=dbo_attendance.ID_Employee
      and dbo_attendance.attend_date > dbo_attendance.attend_date
    order by dbo_attendance.attend_date asc) AS NextDate,
  IIf(IsNull(NextDate),Now(),Nextdate) AS next123,
  Next123-dbo_attendance.attend_date AS difference,
  dbo_attendance.attend_date,
  IIf(dbo_attendance.attend_date+90<Next123,1,0) AS Day90Credit,
  IIf(dbo_attendance.attend_date+90<Next123,dbo_attendance.attend_date+90,dbo_attendance.attend_date+365) AS CreditDate,
  IIf((Day90Credit=0 And CreditDate<Now()) Or Day90Credit=1,1,0) AS TotalCredit
FROM dbo_attendance, dbo_Employees
WHERE (((dbo_Employees.Employee_ID)=[dbo_attendance].[ID_Employee]));

2 个答案:

答案 0 :(得分:2)

sql server(以及大多数其他RDBMS)中,我们使用CASE语句而不是iif()。结构非常简单CASE WHEN <condition> THEN <value if true> ELSE <value if false> END

iif()更改为CASE将是切换的主要部分。但是,第一个iif()更好地表示为COALESCE(),它允许字段或值列表。 Coalesce将从该记录的列表中获取第一个非Null值/字段。

必须切换的其他事情是日期逻辑。在SQL Server中,您使用DATEADD()将日期(或其他日期部分,如年和月)添加到日期。您使用DATEDIFF()减去两个日期来获取日期部分(如天或月或年)。

SELECT dbo_Employees.*,
    (
        SELECT TOP 1 dbo_attendance.attend_date
        FROM dbo_Attendance
        WHERE dbo_attendance.ID_Employee = dbo_attendance.ID_Employee
            AND dbo_attendance.attend_date > dbo_attendance.attend_date
        ORDER BY dbo_attendance.attend_date ASC
        ) AS NextDate,
    COALESCE(NextDate, GETDATE()) AS next123,
    datediff(day, dbo_attendance.attend_date, COALESCE(NextDate, GETDATE())) AS difference,
    dbo_attendance.attend_date,
    CASE 
        WHEN DATEADD(DAY, 90, dbo_attendance.attend_date) < COALESCE(NextDate, GETDATE())
            THEN 1
        ELSE 0
        END AS Day90Credit,
    CASE 
        WHEN DATEADD(DAY, 90, dbo_attendance.attend_date) < COALESCE(NextDate, GETDATE())
            THEN dateAdd(DAY, 90, dbo_attendance.attend_date)
        ELSE DATEADD(DAY, 365, dbo_attendance.attend_date)
        END AS CREDITDATE, 
    CASE 
        WHEN (
                Day90Credit = 0
                AND CreditDate < GETDATE()
                )
            OR DATEADD(DAY, 90, dbo_attendance.attend_date) < COALESCE(NextDate, GETDATE())
            THEN 1
        ELSE 0
        END AS TotalCredit
FROM dbo_attendance,
    dbo_Employees
WHERE dbo_Employees.Employee_ID = [dbo_attendance].[ID_Employee];

最后......我无法记住这在SQL服务器中是如何工作的,因为自从我在环境中已经有一段时间了,但你可能不得不将dbo_的实例切换到dbo.。无论如何,你的服务器会哭泣并让你知道。

答案 1 :(得分:0)

您可以在Sql Server中尝试CTE(公用表表达式)进行复杂计算,请参阅以下链接:https://technet.microsoft.com/en-us/library/ms190766(v=sql.105).aspx

我重构了你的部分查询,如下所示,继续在WITH block下添加你的计算:

WITH Emp_CTE (ID_Employee, attend_date)
AS
(
  SELECT emp.*, 
    (SELECT TOP 1 att.attend_date FROM dbo_Attendance AS att 
      WHERE att.ID_Employee = emp.ID_Employee 
        AND att.attend_date > emp.attend_date 
      ORDER BY att.attend_date ASC) AS [NextDate]
  FROM dbo_Employees
)
SELECT ISNULL(NextDate, GETDATE()) AS [next123],
        ISNULL(NextDate, GETDATE()) - att.attend_date AS [difference]
FROM Emp_CTE;