How do I loop through a table until condition reached - sql-server-2005

I have a table product, pick_qty, shortfall, location, loc_qty
Product Picked Qty Shortfall Location Location Qty
1742 4 58 1 15
1742 4 58 2 20
1742 4 58 3 15
1742 4 58 4 20
1742 4 58 5 20
1742 4 58 6 20
1742 4 58 7 15
1742 4 58 8 15
1742 4 58 9 15
1742 4 58 10 20
I want a report to loop around and show the number of locations and the quantity I need to drop to fulfil the shortfall for replenishment. So the report would look like this.
Product Picked Qty Shortfall Location Location Qty
1742 4 58 1 15
1742 4 58 2 20
1742 4 58 3 15
1742 4 58 4 20

Note that it is best not to think about SQL "looping through a table" and instead to think about it as operating on some subset of the rows in a table.
What it sounds like you need to do is create a running total that tells how many of the item you would have if you were to take all of them from a location and all of the locations that came before the current location and then check to see if that would give you enough of the item to fulfill the shortfall.
Based on your example data, the following query would work, though if Locations aren't actually numerics then you would need to add a row number column and tweak the query a bit to use the row number instead of the Location Number; It would still be very similar to the query below.
SELECT
Totals.Product, Totals.PickedQty, Totals.ShortFall, Totals.Location, Totals.LocationQty
FROM (
SELECT
TheTable.Product, TheTable.PickedQty, TheTable.ShortFall,
TheTable.Location, TheTable.LocationQty, SUM(ForRunningTotal.LocationQty) AS RunningTotal
FROM TheTable
JOIN TheTable ForRunningTotal ON TheTable.Product = ForRunningTotal.Product
AND TheTable.Location >= ForRunningTotal.Location
GROUP BY TheTable.Product, TheTable.PickedQty, TheTable.ShortFall, TheTable.Location, TheTable.LocationQty
) Totals
-- Note you could also change the join above so the running total is actually the count of only the rows above,
-- not including the current row; Then the WHERE clause below could be "Totals.RunningTotal < Totals.ShortFall".
-- I liked RunningTotal as the sum of this row and all prior, it seems more appropriate to me.
WHERE Totals.RunningTotal - Totals.LocationQty <= Totals.ShortFall
AND Totals.LocationQty > 0
Also - as long as you are reading my answer, an unrelated side-note: Based on the data you showed above, your database schema isn't normalized as far as it could be. It seems like the Picked Quantity and the ShortFall actually depend only on the Product, so that would be a table of its own, and then the Location Quantity depends on the Product and Location, so that would be a table of its own. I'm pointing it out because if your data contained different Picked Quantities/ShortFall for a single product, then the above query would break; This situation would be impossible with the normalized tables I mentioned.

Related

How do i join the last record from one table where the date is older than other table?

This is my first post here, and the first problem i havent been able to find a solution to on my own. I have a MainTable that contains the fields: Date, MinutesActiveWork (And other not relevant fields). I have a second table that contains the fields: ID, id_Workarea, GoalOfActiveMinutes, GoalActiveFrom.
I want to make a query that returns all records from MainTable, and the active goal for the date.
Exampel:
Maintable (Date = dd/mm/yyyy)
ID Date ActvWrkMin WrkAreaID
1 01-01-2019 45 1
2 02-01-2019 50 1
3 03-01-2019 48 1
GoalTable:
ID id_Workarea Goal GlActvFrm
1 1 45 01-01-2019
2 2 90 01-01-2019
3 1 50 03-01-2019
What i want from my query:
IDMain Date ActvWrkMin Goal WrkAreaID
1 01-01-2019 45 45 1
2 02-01-2019 50 45 1
3 03-01-2019 48 50 1
The query that i have now is really close to what i want. But the problem is that the query outputs all goals that is less than the date from MainTable (It makes sense why, but i dont know what criteria to type to fix it). Like so:
IDMain Date ActvWrkMin Goal WrkAreaID
1 01-01-2019 45 45 1
2 02-01-2019 50 45 1
3 03-01-2019 48 45 1 <-- Dont want this one
3 03-01-2019 48 50 1
My query
SELECT tblMain.Date, tblMain.ActiveWorkMins, tblGoal.Goal
FROM VtblSumpMain AS tblMain LEFT JOIN (
SELECT VtblGoalsForWorkareas.idWorkArea, VtblGoalsForWorkareas.Goal, VtblGoalsForWorkareas.GoalActiveFrom (THIS IS THE DATE FIELD)
FROM VtblGoalsForWorkareas
WHERE VtblGoalsForWorkareas.idWorkArea= 1) AS tblGoal ON tblMain.Date > tblGoal.GoalActiveFrom
ORDER BY tblMain.Date
(I know i could do this pretty simple with Dlookup, but that is just not fast enough)
Thanks for any advice!
For this, I think you have to use the nested query as I mention below.
select tblMain.id,tblMain.Date,tblMain.ActvWrkMin, tblMain.WrkAreaID,
(select top 1 Goal
from GoalTable as gtbl
where gtbl.id_workarea = 1
and tblmain.[Date] >= gtbl.glActvFrm order by gtbl.glActvFrm desc) as Goal
from Maintable as tblMain
Check the below image for the result which is generated from this query.
I hope this will solve your issue.

Need SQL query for Comparing Duplicate Value and print respective column name

HI expert and need your help me on the below requirement in oracle.
I have list of columns and from that I need to know based on the Model No. column filter if the other columns have any duplicate values, if yes then it should display comments column as Column Name + duplicate value (Ex: Category_description having duplicate value)
If the any of the column is blank it should print Column Name is blank (Ex: Parent Category ID has blank value).
The data is:
M_No CAT_DESC CAT_ID P_CAT_ID Comments
1 computer hardware 10 90
1 monitors 11 10
1 printers 12 10
1 harddisks 13 10 CAT_DESC duplicate
1 memory components 14 10
1 harddisks 15 10 CAT_DESC duplicate
1 keyboards, mouses 16 10
1 other peripherals 17 10
1 harddisks 19 10 CAT_DESC duplicate
2 office fur supplies 30 90
2 capitalizable assets 31 30
2 office daily use 32 30
2 manuals, other books 33 30 CAT_DESC, CAT_ID duplicate
2 manuals, other books 33 30 CAT_DESC, CAT_ID duplicate
3 computer hardware 90 P_CAT_ID is blank value
4 computer software 20 90
4 spreadsheet software 21 20
4 processing software 22 20
4 23 CAT_DESC, P_CAT_ID is blank
4 operating systems 24 20
4 software development 25 20
4 miscellaneous software 29 20

MS Access - Dynamic Crosstab Query - VBA for Totals Row that provides Column totals

I have built a dynamic crosstab query where the user selects options from multiple combo boxes and then I use VBA to update the SQL for the cross tab query. It is then, in turn, displayed on a subform. My question is basically how can I programmatically (VBA or SQL, don't really care either way) add a totals row that calculates the average of each column. I know how to do this manually, but since the number of columns and column headings are not set, this is impractical. I would basically like to automatically set a totals row at the bottom for the average of each column regardless of the number of columns or column headers. An example of a potential case is shown below with the user inputs on top.
Group: A
Team: All
Start Date: 1/1/2014
End Date: 5/31/2014
Query Type: Monthly
Name 2014-Jan 2014-Feb 2014-Mar 2014-Apr 2014-May
John Doe1 1 2 3 4 5
John Doe2 2 2 2 2 2
John Doe3 1 5 9 13 17
John Doe4 2 10 18 26 34
John Doe5 1 8 15 22 29
John Doe6 2 12 22 32 42
John Doe7 1 15 29 43 57
John Doe8 2 14 26 38 50
John Doe9 1 12 23 34 45
Total (Avg): 1.44 8.89 16.33 23.78 31.22
I am trying the generate the bottom "Totals" row programmatically without knowing the column count ahead of time and without manually inserting totals via the ribbon.
You can use a pivot table on a simple select query.
Doesn't the crosstab query do that for you?
https://support.office.com/en-us/article/Make-summary-data-easier-to-read-by-using-a-crosstab-query-8465B89C-2FF2-4CC8-BA60-2CD8484667E8
http://www.fmsinc.com/microsoftAccess/query/crosstab-report/index.html
Although crosstab queries are somewhat limited in their power, you can certainly create another query to do a basic average of the crosstab query you just created.

select previous row value for same user (multiple records)

I have a query in Access 2010 (have also tried on 2013, same result) that is working but not perfectly for all records. I'm wondering if anyone knows what is causing the error.
Here is the query (adapted from http://allenbrowne.com/subquery-01.html#AnotherRecord):
SELECT t_test_table.individ, t_test_table.test_date, t_test_table.score1, (SELECT top 1 Dupe.score1
FROM t_test_table AS Dupe
WHERE Dupe.individ = t_test_table.individ
AND Dupe.test_date < t_test_table.test_date
ORDER BY Dupe.primary DESC, Dupe.individ
) AS PriorValue, [score1]-[priorvalue] AS scorechange
FROM t_test_table;
The way the data is set up, an individual has multiple records in the file (designated by individ) representing different dates a test was taken. A date AND individ combination are unique - you can only take a test once. [primary] refers to primary key column. I just made it because the individ field is not a primary key since multiples are possible (I'm not including it here due to space)
The goal of the above code was to create the following:
individ test_date score1 PriorValue scorechange
1 3/1/2013 40
1 6/4/2013 51 40 11
1 7/25/2013 55 51 4
1 12/13/2013 59 55 4
5 8/29/2009 39
5 12/9/2009 47 39 8
5 6/1/2010 58 47 11
5 8/28/2010 42 58 -16
5 12/15/2010 51 42 9
Here is what I actually got. You can see that for individ 1, it winds up taking the first score rather than the previous score for each subsequent record. For individ 5, it kind of works, but the final priorvalue should be 42 and not 58.
individ test_date score1 PriorValue scorechange
1 3/1/2012 40
1 6/4/2012 51 40 11
1 7/25/2012 55 40 15
1 12/13/2012 59 40 19
5 8/29/2005 39
5 12/9/2005 47 39 8
5 6/1/2006 58 47 11
5 8/28/2006 42 58 -16
5 12/15/2006 51 58 -7
Does anyone have any ideas about what went wrong here? In other records, it works perfectly, but I can't determine what is causing some records to fail to take the previous value.Any help is appreciated, and let me know if you require additional information.
To get the most recent test for a given individ, you'll need to include a sort by date. In your inner query, replace
ORDER BY Dupe.primary DESC, Dupe.individ
with
ORDER BY Dupe.test_date DESC
It's hard to say exactly what effect sorting by primary has, since you haven't told us how you're generating the values of primary. If the combination of individ and test_date is guaranteed to be unique, you might want to consider making the two of them into your primary key instead of creating a new thing. The Dupe.individ in the ORDER BY line has no effect, since your WHERE clause already limited the results of the inner query to one individ.

Create a Multi-Column Report Using DevEx Grid

I have a daily sales report query and it have 2 columns like
days sales
1 12
2 65
3 25
...
30 24
but when I want to print it there is a lots of free spaces on paper, so I want to seperate query with a percentage (like % 33)
and result will be like 3 x 2 columns for one paper. and it will be more comfortable for me.
days sales days sales days sales
1 12 11 21 21 5
2 65 12 53 22 18
3 25 13 0
...
10 45 20 12 30 55
Any way to do this with DevEx Grid?
this is the view which I get
and I dont want such kind of empty paper for couple of records..
You will not find an easy way to achieve the desired result using XtraGrid, because it is not intended for reporting. I suggest that you create reports using another product: XtraReports.