Issue when joining 3 temp tables - sql-server

I have an issue joining 3 temp tables.
I am going to write the whole code but the thing that doesn't work is a join when selecting all three temp tables. Everything else works just fine (type just in case if someone wants to see the whole picture).
I need to join all three tables on dates to make sure I select the same inventory during the same time period. Whenever I join those three tables I either get Forecast or Actuals right, but never both.

When I type this I get Forecast correct, but Actuals incorrect a.[DMDPostDate]=u.[STARTDATE] and f.[STARTDATE]=a.[DMDPostDate] (Forecast correct 6998.649, Actuals are not correct 826)
-- AND u.[STARTDATE]=f.[STARTDATE] and f.[STARTDATE]=u.[STARTDATE] (Actuals are correct 10369, Forecast not correct 8322.315)
-- and a.[DMDPostDate]=f.[STARTDATE] (Forecast correct 6998.649, Actuals not correct)
-- AND u.[STARTDATE]=a.[DMDPostDate] (Forecast correct 6998.649, Actuals not correct)
-- AND u.[STARTDATE]=f.[STARTDATE] (Actuals are correct 10369, Forecast not correct)
-- and u.[STARTDATE]=f.[STARTDATE] and u.[STARTDATE] = a.[DMDPostDate] (Forecast correct 6998.649, Actuals not correct)
From your post - it seems fairly clear that joining STARTDATEs gets you the correct actuals, and joining DMDPostDate to either start date gets the right forecast.
Something thing to consider - u.[STARTDATE]=f.[STARTDATE] - this clause should have no impact to the A table join, what if you added this to the F table ON clause, and then u.[STARTDATE] = a.[DMDPostDate] to the A table clause
The way it's working now, you're left joining everything from table F to everything it can join to in table A based on the U.[UPC]=F.[DMDUNIT] AND U.[MASTERCHAINNAME]=F.[LOC], without any dates. It could be a challenge with the way it's evaluating the clauses as a result.
Dark horse answer - you don't need to join on any dates - actuals are correct when you aren't joining dates for the A table - when you use AND u.[STARTDATE]=f.[STARTDATE] it may be applying to the U/F join which could lower the forecast number.
You could also troubleshoot by joining the F and A tables separately to the U table to see if you're getting the expected values then.
Best guess -
SELECT
U.[UPC] AS 'Item',
U.[MASTERCHAINNAME] AS 'Chain',
U.[STARTDATE] AS 'Start Date',
U.[EVENT_TYPE] ,
U.[EVENT_NAME],
SUM(F.Forecast) AS 'Forecast',
SUM(A.HistoryQuantity) AS 'Actuals'
FROM
UDT_CKB_SNAPSHOT U
LEFT OUTER JOIN
FCSTPERFSTATIC F ON U.[UPC] = F.[DMDUNIT]
AND U.[MASTERCHAINNAME] = F.[LOC]
AND f.[STARTDATE] = u.[STARTDATE]
LEFT OUTER JOIN
HISTWIDE_CHAIN A ON U.[UPC] = a.[DMDUNIT]
AND U.[MASTERCHAINNAME] = a.[LOC]
AND a.[DMDPostDate] = u.[STARTDATE]
GROUP BY
U.[UPC], U.[MASTERCHAINNAME], U.[STARTDATE], U.[EVENT_TYPE] , U.[EVENT_NAME]

Related

Find the Min and Max date from two tables from a sql select statement

Cant seem to wrap my head round this problem.
I have two tables one which has the following sample values:
Second table had the following values:
What i am trying to achieve is like the following:
So you can see the first table has the modules, what year and what term.
Based on these there is a start week and and end week.
The lookup table for the start and the finish unfortunatley is in a week basis and i need the begin week to match the second tables weekNo based on the season i guess and taking the start date being Sdate from that table to match what i am looking for and then the same applies to the end date.
Match the season and the endweek with the second tables WeekNo and Edate and only bring that date in.
Hope i made a bit of sense but i am hoping the third image shows what i am look for.
I've tried CTE, Group by, Partition by, order by, min, max and got nowhere :(
Dont really want to hard code anything, so was hoping you wonderful peps can help me out !!
Many thanks in advance :)
I suspect you are trying to achieve this by using one a single join between the tables - whereas what you actually need is two separate joins:
SELECT table1.module as mod_code,
table1.season as psl_code,
table2.Sdate as ypd_sdate,
table3.Edate as ypd_edate
FROM t1 as table1
JOIN t2 as table2 ON table2.yr = table1.year AND table2.season = table1.season AND table2.weekNo = table1.BeginWeek
JOIN t2 as table3 ON table3.yr = table1.year AND table3.season = table1.season AND table3.weekNo = table1.EndWeek

I have two tables and wanted to make a left join and get the latest data using date from both the tables. It doesn't pull all data from left table

I have two tables and wanted to make a left join and get the latest data using date from both the tables. It doesn't pull all data from left table
SELECT Firsttable.Username, Secondtable.city
FROM Firsttable
LEFT JOIN Secondtable ON (Firsttable.Username = Secondtable.Account_Name)
WHERE (
Firsttable.Questions <> 5
AND Firsttable.CreateDate = '2018-02-06 09:41:38.000'
AND Secondtable.CreateDate = '2018-02-06 09:07:47.000'
)
OR (
Firsttable.Questions <> 5
AND Firsttable.CreateDate = '2018-02-06 09:41:38.000'
AND Secondtable.CreateDate IS NULL
)
Since you didn't provide us with any data, you are going to have to do your own testing.
First, break your query down into smaller parts and see if the data you want actually exists.
SELECT Firsttable.Username
FROM Firsttable
LEFT JOIN Secondtable ON
(Firsttable.Username = Secondtable.Account_Name
AND Firsttable.Questions <> 5
AND Firsttable.CreateDate = '2018-02-06 09:41:38.000'
)
This will show if you have data in the first table that is valid. If you don't get anything, you may need to relax your Date comparison by eliminating Time. But only you know how restricting your data is. It also may mean your Secondtable.Account_Name may not match up to your Firsttable.Username like you thought. Play around with this query until you get the good data you were expecting.
Once you know you have good data in your first table, then add on selection criteria for your second table:
SELECT Firsttable.Username, Secondtable.city
FROM Firsttable
LEFT JOIN Secondtable ON
(Firsttable.Username = Secondtable.Account_Name
AND Firsttable.Questions <> 5
AND Firsttable.CreateDate = '2018-02-06 09:41:38.000'
)
WHERE (
Secondtable.CreateDate = '2018-02-06 09:07:47.000'
OR Secondtable.CreateDate IS NULL
)
If this drops off all of your data, then you know something doesn't match up with your Secondtable.CreateDate. It could be your use of Time is too constricting. Just match on date only and see if that helps. But if you know Time is important, go back to the first query above and print out all the different Secondtable.CreateDate to see if your date is part of the result set. Being off by one second could cause your data to not match.
Play around with both of these queries until you find the combination that brings your data out.
If you still have trouble, you'll have to post some example data for each table so we can see how to help you better.

Duplicate SQL Record Entries with in 3 days

Table has following structure
ID, OrderNumber, PFirstName, PLastName, Product, LastDateModified
This information is populated into my SQL Server database by a XML import file and is created when the front end hits 'Enter'. But someone on the front has been seeing an error and then hitting Cancel and re-submitting the order with new information.
Now, the first order is in the Database because they didn't cancel it out on the backend first.
How can I find the any duplicate OrderNumber, PFirstName, PLastName, Product within 3 days of any lastdatemodified entry?
A self join with a simple where clause.
Assuming the ORDER numbers are not duplicated and that's what you're looking for.
SELECT A.ID as A_ID
, A.orderNumber as OriginalOrder
, B.ID as B_ID
, B.OrderNumber as PossibleDuplicatedOrder
FROM TBL A
INNER JOIN TBL B
on A.PFirstName = B.PfirstName
AND A.PLastName = B.PLastName
AND A.Product = B.Product
AND A.LastDateMOdified < B.LastDateModified
WHERE datediff(day,A.LastDateModified,B.LastDateModified) <=3
Logically this self joins and to eliminate A-->B and B-->A duplication casued by self joins we use a < so that all of the records in alias A have a date earlier than that in B when the other fields are equal, and then we simply look for those that have a datediff of <=3.
However if multiple duplicates exist for the same order such as
A-->B
B-->C
You'll see duplication in the results such as (but only if all 3 are w/in 3 days)
A-->B
B-->C
A-->C
But I don't see this as a bad thing given what you're attempting to recover from.
I'm not sure how to determine if it's been cancelled or backed out so you'll have to set other limits for that as they weren't specified in the question.

Performance issue with DATEADD function

This is my actual select query,
SELECT b.CaseNumber as CaseNumber,b.DebtorNr ,b.ActionDate,DATEADD(MONTH,-12,b.ActionDate) one_month,a.Registerdate --COALESCE(count(A.historynr),0) as DebtorActivity
from rr..r_basic_info b
join rr..activities_VW as A on b.DebtorNr=a.Debtornr
where
B.Debtornr = A.Debtornr
--and a.Registerdate<=b.ActionDate --this condition works
and a.registerdate >= DATEADD(month,-12,getdate()) --i have a problem with this condition and causing huge time consumption
I have a view defined here is activities_VW
select H.NR as historynr,o.debtornr as Debtornr, O.NR as ordernr, h.Actmenunr as Actmenunr,h.AGREEMENT as AgreementCode, h.Registerdate as Registerdate
from abc..history h join abc..orders o on o.NR=h.ORDERNR
and my execution plan is like
One more information for all rows b.actionDate column has identical value like '2015-04-11 08:37:44.037'.
I have checked with all date format but nothing wrong found.
For another case, I have different value for different rows in b.actionDate column and it is working fine for that case.
Thanks
I may be wrong in my understanding so take it only as a possibility - when using a function within a join criteria and/or where clause, in order to determine if data meets the criteria, it must be checked against every row in the table.
Think about your first part WHERE e.DATE <= a.joining_date - you can simply look directly at rows that are less than the e.DATE.
For your second part AND e.DATE >= DATEADD(MONTH, - 6, a.joining_date) - there is no column the is "joining date minus 6 months", so to determine if e.Date is greater than it, you would need to perform that calculation on every instance of a.joining_date in the table.
Remember that where clause information is not necessarily evaluated in the order is it written down in the query - so the rows you would think are eliminated by the first part of your where are not necessarily eliminated by it. So as one of the comments suggested, using a computed/persisted column on the DATEADD(MONTH, - 6, a.joining_date) would probably work well.
This is my actual select query,
SELECT b.CaseNumber as CaseNumber,b.DebtorNr ,b.ActionDate,DATEADD(MONTH,-12,b.ActionDate) one_month,a.Registerdate --COALESCE(count(A.historynr),0) as DebtorActivity
from rr..r_basic_info b
join rr..activities_VW as A on b.DebtorNr=a.Debtornr
where
B.Debtornr = A.Debtornr
--and a.Registerdate<=b.ActionDate --this condition works
and a.registerdate >= DATEADD(month,-12,getdate()) --i have a problem with this condition and causing huge time consumption
I have a view defined here is activities_VW
select H.NR as historynr,o.debtornr as Debtornr, O.NR as ordernr, h.Actmenunr as Actmenunr,h.AGREEMENT as AgreementCode, h.Registerdate as Registerdate
from abc..history h join abc..orders o on o.NR=h.ORDERNR
and my execution plan is like
One more information for all rows b.actionDate column has identical value like '2015-04-11 08:37:44.037'.
I have checked with all date format but nothing wrong found.
For another case, I have different value for different rows in b.actionDate column and it is working fine for that case.
Thanks

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.

Resources