MSSQL, how compare records with dataframe table? - sql-server

let's say we have a table with invoices and employees ID
and another table for vacation which also contains an employee ID.
In this case only emplyee1 had vacation a these date frames.
Now we have to compare if the invoice date is between or exactly at the date frames of vacation table.
The aim is: The invoice date has to be compared, if an employee is on vacation the calc_flag = 0, if not then always=1. E.g. employee1 was from 2023/01/05 till 2023/01/12 on vacation.
So all his invoices must be calc_flag=0 for this time.
How to create the sql query in mssql for this topic?
Thanks for any advice.
I already tried to check the dateframes but if there are several entries in vacation table, I'm not sure how to handle it.

One way to do this is a LEFT JOIN to check for existance. Perhaps you need to tweak the < or > depening if you would like to include the Begin and or End date.
SELECT i.InvNo,
i.emp_ID,
i.InvDate,
i.calc_flag ,
CASE WHEN v.Emp_ID IS NOT NULL THEN 0 ELSE 1 END AS calc_flage
FROM dbo.invoices AS i
LEFT JOIN dbo.vacation AS v ON v.Emp_ID = i.emp_ID AND v.[Begin] < i.InvDate AND v.[End] > i.InvDate

Related

Add values to a table from a second table that only match a third table allowing for duplicates

I have been tasked to match a payment file from a bank that has invoices/payments listed on a text file I have imported into a table called Bank. I need to match the invoices to the project/projects that are associated with the invoices - call this table Invoices - which contains every invoice and project we have every had. I want to match the invoices (from Bank) to the project or multiple projects (from Invoices) to another table - called Report - so I can reconcile the payment file. I can get the correct results from Bank and Invoices with the following query
SELECT invoice
FROM Invoices INV
INNER JOIN Bank as BANK
ON INV.Invoice = BANK.Invoice_Number
The Bank file has 100 invoices and I get 169 invoices on this query. But when I try and do and update or insert
Update Report
set Invoice_Num =
(SELECT invoice
FROM Invoices INV
INNER JOIN Bank as BANK
ON INV.Invoice = BANK.Invoice_Number)
I get 0 rows updated.
I have tried to copy the Bank table to the Report table with
Insert into Report(Invoice_Num)
select Invoice_Number from Bank
but can't figure out how to account for the projects that have duplicated invoices when they are found. Of course I might be going at this entirely wrong and someone has a better way entirely.
Thanks!
Does your Report table have anything in to start with? If not, your UPDATE statement will update 0 rows, because there are 0 rows there to update. (Also, with your code as it stands, note that it would update every entry there to have the same, indeterminate value; I don't think that's what you intend.)
If you just want to copy the invoice numbers from Bank to Report, but leave out any duplicates, then your final bit of SQL just needs a DISTINCT added to do that:
Insert into Report(Invoice_Num)
select DISTINCT Invoice_Number from Bank
If you're trying to put in only invoice numbers from Bank that also match Invoice, then your first bit of code almost works, but needs to be an INSERT, not an UPDATE:
INSERT INTO report (invoice_number)
SELECT invoice
FROM Invoices INV
INNER JOIN Bank as BANK
ON INV.Invoice = BANK.Invoice_Number
Again, if you're also dealing with potential duplicates invoice numbers you only want in Report once, make that a SELECT DISTINCT to avoid them.

SQL - Perform a count statement using a date range temp table and a list of customers with start/end contract date (2nd temp table)

- I'm currently trying to perform a count function using information coming from two temp tables. One table has only a list of dates Jan 1 2018 - Dec 31 2018 (temp table 1), and another table has customer info, approx 100 customers (temp table 2), including contract start and end dates. These two tables cannot be joined. My goal is to perform a count for each date in temp table 1, for example: if temp table 1 date is 1/1/2018 , I'd like to count how many contracts were active on that day, if a customer contract start date is 12/5/2017 and end date 12/31/2021 I want that customer to be counted, and so on. If customer contract date ends on 12/31/2017, I do not want that customer to be counted for 1/1/2018, if customer start date is 1/2/2018, I do not wish to count that customer on 1/1, only 1/2 and on. I hope this is enough info. Thank you
Assuming that you have table structures as follows :
table customers : has columns start_date and end_date, that represent the start and end date of the contract.
table dates : has a column called my_date
(and also assuming that all above columns are of datatype DATE or equivalent)
Then you want to JOIN both tables like :
SELECT
d.my_date,
COUNT(*) -- number of active contracts at that date
FROM customers c
INNER JOIN dates d ON d.my_date BETWEEN c.start_date AND c.end_date
GROUP BY d.my_date
Select mydate,Count(*) as activecount from tab2
where mydate > (select startdate from tab2)
and mydate <(select enddate from tab2)
group by mydate

Customer Attrition in SQL Server

I am trying to find churned customer in the adventureworks2012 sample database. Churned customer in my case is a customer who used to be active in a period of six months, then has not made any transaction in a later period of time.
My attributes are customer ID, product category, product subcategories, price, order dates, online order flag etc
Can you please provide some hints on how to define teacher customer as either churned or not churned.
Thank you in advance.
If you're trying to loop through them all:
SELECT TEACHER_ID, MAX(ORDER_DATE) FROM ORDERS GROUP BY TEACHER_ID
Will give you each teachers last order date, and then you can loop through and compare them to whatever date range you want (if you're doing a loop).
If you're trying to figure out an individual teacher just see if the count is > 0:
SELECT COUNT(*) AS COUNT FROM ORDERS WHERE TEACHER_ID = ? AND ORDER_DATE > (NOW() - INTERVAL 6 MONTH)
Best I can do w\o a better idea what language you're using and what the application is.

A challenge for you SQL lovers out there

I'm new to the working world an am fresh out of varsity. i started working an am creating a few reports via SQL reporting services as part of my training.
Here is quite a challenge that I am stuck at. Please help me finish this query. Here is how it goes!
There are several employees in the employee_table that each have unique identifier known as the emp_id
There is a time_sheet table that consists of several activities AND THE HOURS FOR EACH ONE for the employees and references them via emp_id. Each activity has a TIMESHEET_DATE that corresponds to the day all the activities were submitted(once a month). There are several activities with the same date because all those activities were submitted on the same day.
And there is a leave table that references the employees via emp_id. In the leave table, there is a column for the amount of days they took off and the starting day (Leave_FROM) of the leave.
I must create a parameter where the user inputs the month (easy peasy)...
Now in the report, column 1 must have their name (easy), column 2 must have their totals hours for the specified month (HOURS) and column 3 must show how many days they took leave for that month specified.
It can be tricky, not everybody has a entry in the leavetable, but everybody has got activities in the Time_Sheet table.
Here is what I have gotten so far from a query, but its not really helping me.
Unfortunately, I cannot upload pictures, so here is a link
http://imageshack.com/a/img822/8611/5czv.jpg
Oh yea, my flavor of SQL is SQL Server
You have a few different things you need to attack here.
First is getting information from the employee_table, regardless of what is in the other two tables. To do this, I would left join on both of the tables.
Your second battle is, now since you have multiple rows in your time_sheet table, you are going to get a record for every time_sheet record. That is not what you want. You can fix this by using a SUM Aggregate and a GROUP BY clause.
Next is the issue that you are going to have when nothing exists in leave table and it is returning NULL. If you add an ISNULL(value,0) around your leave table field, it will return 0 when no records exist on that table (for that employee).
Here is what your query should look like (not exactly sure on table/column naming):
I changed the query to use temp tables, so totals are stored separately. Since the temp tables will hold 0 for employees that don't have time/leave, you can do an inner join on your final query. Check this out for more information on temp tables.
SELECT e.emp_id, ISNULL(SUM(ts.Hours),0)[Time]
INTO #TotalTime
FROM employee e
LEFT JOIN time_sheet ts ON e.emp_id = ts.emp_id
GROUP BY e.emp_id
SELECT e.emp_id, ISNULL(SUM(l.days),0) [LeaveTime]
INTO #TotalLeave
FROM employee e
LEFT JOIN leaveTable l ON e.emp_id=l.emp_id
GROUP BY e.emp_id
SELECT e.Emp_Id,Time,LeaveTime FROM Employee e
INNER JOIN #TotalTime t ON e.Emp_Id=t.Emp_Id
INNER JOIN #TotalLeave l ON e.Emp_Id=l.Emp_Id
DROP TABLE #TotalLeave,#TotalTime
Here is the SQL Fiddle
Left join the leave table, if nobody took leave you won't get any results.

sql server procedure to update table on conditions

I am trying to write a stored procedure that will run every day and check invoices for past due or not. I want to pull all invoices from table that are not paid then I want to go through them and find the difference between todays date and the date the order was placed. From there I want to check what the account terms for that order are( basically how long they have to pay) and if they have gone over the terms then I will calculate a service charge and update balancedue. I have a basic idea of what to do but I don't know how to go through the selected records without looping through each one. I thought there was a better way to do it in sql server.
The invoice table has an accountid, ispaid, and creationdate. The account table as the terms for the account. Then I have an accountbalance table with several fields I would update if needed.
Accountbalance fields
balancedue
pastdue30
pastdue60
pastdue90
pastdueover90
The accountid can get me from invoice to account and accountbalance and the date can give me how long it has been, I then would just update the accountbalance accordingly to terms and how long it has been past due. I know its a little hard to understand without seeing it.
This is what I am basically trying to do I am just not sure how to do it for each record
select * from invoice where ispaid = 0
days = currentdate - invoicecreationdate
switch (days)
case 30
update balance
case 60
update balance
case 90
update balance
if(days > terms)
update balance add servicecharge
Your additions help, but I'm still a little unsure on what's going on here (for example, what are the pastdueXX fields in Accountbalance and how do they relate to the balancedue field?). Also, can one account have multiple past due invoices?
It sounds like you're looking for something similar to the following:
update ab set balancedue =
(case when datediff(i.creationdate,getdate()) > 90 then balance due + ...
when datediff(i.creationdate,getdate()) > 60 then balance due + ...
...
end)
from accountbalance ab
join account a
on ab.accountid = a.accountid
join invoice i
on a.accountid = i.accountid
Sorry for the vagueness, but again, still have some questions.

Resources