0

I have a MS Access query and I want to convert in SQL Server query, any help will be greatly appreciated.

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]));
1
  • 1
    You might consider posting your attempt to run it on SQL Server either converted or as is with error reported if any. Commented Mar 4, 2016 at 19:09

2 Answers 2

2

In sql server (and most every other RDBMS) we use CASE statements instead of iif(). The structure is pretty simple CASE WHEN <condition> THEN <value if true> ELSE <value if false> END.

Changing your iif() over to CASE will be the bulk of the switch over. The first iif() however is better represented as a COALESCE() which allows a list of fields or values. Coalesce will grab the first Non-Null value/field from the list for that record.

The other things that have to be switched is the Date logic. In SQL Server you use DATEADD() to add days (or other date parts like year and month) to a date. you use DATEDIFF() to subtract two dates to get a date part (like Days or Months or Years).

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];

Lastly... I can't remember how this works in SQL server since it's been a while since I was in the environment, but you might have to switch instances of dbo_ to dbo.. Your server will cry foul and let you know anyhow.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks JNevill, I will try and inform you.
Msg 102, Level 15, State 1, Line 9 Incorrect syntax near 'day'.
Missing a comma after the COALESCE(). I've updated the answer.
Sorry for the volley of updates hitting this. I'm trying to update the SQL to reflect the change, while someone else is cleaning up the formatting (which I appreciate) and we keep hitting conflicts. I believe it's good as of the time of this comment.
Thanks JNevill again, but I am getting errors on all the AS Statements.Msg 207, Level 16, State 1, Line 18 Invalid column name 'NextDate'.Msg 207, Level 16, State 1, Line 24 Invalid column name 'Day90Credit'.Msg 207, Level 16, State 1, Line 27 Invalid column name 'NextDate'.
|
0

You can try CTE (Common Table Expressions) in Sql Server for complex calculations, see this link: https://technet.microsoft.com/en-us/library/ms190766(v=sql.105).aspx

I refactored part of your query as below, proceed adding your calculations under 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;

1 Comment

Thanks M. Fawad Surosh, will you help me to convert my query to CTE?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.