Rails : Calling a function in a loop returns same value for each iteration - ruby-on-rails-3

I am trying to calculate Leave taken by a particular student "UG10001" in a particular month from a leaves table in mysql database. I am using following snippets of code--
def calculate(student_id)
leave = Leave.find_by_sql("SELECT leave_duration FROM leaves WHERE MONTH(leave_from) = 2
AND YEAR(leave_from) = 2013 AND MONTH(leave_to) = 2 AND YEAR(leave_to) = 2013 AND
academic_status = 'APPROVED' AND warden_status = 'APPROVED' AND student_id = student_id
AND status = 'ACTIVE'")
sum = leave.sum(&:leave_duration)
return sum
end
----------Update----------
def calculate(student_id)
sum = Leave.find_by_sql("SELECT leave_duration FROM leaves WHERE MONTH(leave_from) = 2
AND YEAR(leave_from) = 2013 AND MONTH(leave_to) = 2 AND YEAR(leave_to) = 2013 AND
academic_status = 'APPROVED' AND warden_status = 'APPROVED' AND student_id = student_id
AND status = 'ACTIVE'").sum(&:leave_duration)
return sum
#it did the trick for me.
end
The above method will calculate the leave taken by a particular student in the month of February '13 and returns the sum of the leaves to the calling function.
def calcuateLeaveForEachStudent
array = Leave.find_by_sql("select student_id from students")
c = Array.new
for i in 0...array.length
student_id = array[i].student_id
c[i] = calculate(student_id)
end
end
But when I call the above method, 'calculate' method returns the same value on each iteration. What could be the possible solution for this..? Thanks in advance..!
PS -
Code runs perfectly on Rails Console without any syntactical errors, however there is some error I can't figure out.

calculate(operation, column_name, options = {}).
or you can refer the link

Related

What is the Purpose of the IsNull in this query?

I have a desktop application that I am converting to web and I am having trouble understanding the purpose of the IsNull parts of the query. The query is for Ms SQL and I know it has a IsNull function but this is not it. So I'm confused as to it's purpose. Below is my query:
UPDATE tb_category
SET
Email = #Email,
CandidateID = #CandidateID,
Code = #Code,
TestDate = #TestDate,
Description = #Description,
PointsEarned = #PointsEarned,
PointsAvailable = #PointsAvailable,
Average25th = #Average25th,
Average75th = #Average75th,
ImportedDate = #ImportedDate,
CreationDate = #CreationDate,
TestNum = #TestNum,
CategoryNum = #CategoryNum
WHERE ((Email = #Original_Email)
AND (CandidateID = #Original_CandidateID)
AND (Code = #Original_Code)
AND (TestDate = #Original_TestDate)
AND ((#IsNull_Description = 1 AND Description IS NULL) OR (Description = #Original_Description))
AND (PointsEarned = #Original_PointsEarned)
AND ((#IsNull_PointsAvailable = 1 AND PointsAvailable IS NULL) OR (PointsAvailable =
#Original_PointsAvailable))
AND ((#IsNull_Average25th = 1 AND Average25th IS NULL) OR (Average25th = #Original_Average25th))
AND ((#IsNull_Average75th = 1 AND Average75th IS NULL) OR (Average75th = #Original_Average75th))
AND ((#IsNull_ImportedDate = 1 AND ImportedDate IS NULL) OR (ImportedDate = #Original_ImportedDate))
AND ((#IsNull_CreationDate = 1 AND CreationDate IS NULL) OR (CreationDate = #Original_CreationDate))
AND (TestNum = #Original_TestNum)
AND (CategoryNum = #Original_CategoryNum));
I tried simplifying the update statement by removing the IsNull sections but that did not work.
In SQL null is not equal (=) to anything—not even to another null, so in your query in case if both values are null (old and new one) you need to take that into account and check values with IS NULL.
I'm seeing this pattern repeated several times in the WHERE clause:
#IsNull_Description = 1 AND Description IS NULL
It means that a variable, #IsNull_SomeColumnName, which is presumably set earlier in the code, has a value of 1, and the column that the variable relates to is currently NULL.
The function IsNull(Param1, Param2) is used to substitute the value of the second parameter for the value of the first parameter if the first parameter IS NULL, and the function returns the value of Param2.
In SQL Server, and quite a few other RDBMSs, the IS NULL syntax is used to check if a value is currently NULL. Here, Description IS NULL will return TRUE if, well, Description is null, and FALSE if it is not.

My while loop is running forever by calculating and inserting the records into a table

I have created a while loop to check if my derived value is less than zero then enter into while loop, increment my Period ID to +1, pull the values from that period and run the logic again.
But my T SQL code is running forever with this logic with the 26000 records which is not a huge data.
Below is my code logic
SELECT #lclcurrentperiod = PERIOD_ID,
#snop_item = FGA_ID,
#lclfullfill_center = fulfillment_center,
#lcldepo_wise_sawtd = DEPOT_WISE_SAWTD,
#lclDemandType = DEMAND_TYPE,
#lclDepo_wise_final = DEPOT_WISE_FINAL,
#lcldepo_wise_forecast = DEPOT_WISE_FORECAST
FROM temp_calc (NOLOCK)
WHERE PERIOd_id IN (SELECT MIN(period_id)FROM temp_calc WHERE depot_wise_forecast > 0)
AND FGA_ID = #fga_id
AND fulfillment_center = #lclFulfillmentCenter
AND DEMAND_TYPE = 'TRANSACTIONAL';
SET #net_offset_forecast = #lclDepo_wise_forecast - #forecast_consumed_by_sales;
INSERT INTO NET_OFFSET_FORECAST (PERIOD_ID,
FGA_ID,
FULFILLMENT_CENTER,
DEMAND_TYPE,
LEGACY_SSC,
DEPOT_WISE_FORECAST,
CUM_FORECAST,
DRAFT_NET_FORECAST,
FORECAST_TO_BE_CONSUMED,
NET_OFFSET_FORECAST)
VALUES (#lclCurrentPeriod, #snop_item, #lclfullfill_center, #lclDemandType, #lclLegacySSC, #lclDepo_wise_forecast, #cum_forecast, #draft_net_forecast, #forecast_consumed_by_sales, #net_offset_forecast);
WHILE (#net_offset_forecast < 0)
BEGIN
SET #lclcurrentperiod = #lclcurrentperiod + 1;
SET #forecast_consumed_by_sales = ABS(#net_offset_forecast);
SELECT #lclcurrentperiod = PERIOD_ID,
#fga_id = FGA_ID,
#lclFulfillmentCenter = FULFILLMENT_CENTER,
#lclDepo_wise_forecast = DEPOT_WISE_FORECAST,
#lclDemandType = DEMAND_TYPE
FROM (SELECT *,
ROW_NUMBER() OVER (ORDER BY PERIOD_ID) AS RN
FROM TEMP_CALC
WHERE DEPOT_WISE_FORECAST > 0
AND FGA_ID = #fga_id
AND fulfillment_center = #lclFulfillmentCenter
AND DEMAND_TYPE = 'TRANSACTIONAL') t
WHERE RN = 1;
SET #net_offset_forecast = #lcldepo_wise_forecast - #forecast_consumed_by_sales;
INSERT INTO NET_OFFSET_FORECAST (PERIOD_ID,
FGA_ID,
FULFILLMENT_CENTER,
DEMAND_TYPE,
LEGACY_SSC,
DEPOT_WISE_FORECAST,
CUM_FORECAST,
DRAFT_NET_FORECAST,
FORECAST_TO_BE_CONSUMED,
NET_OFFSET_FORECAST)
VALUES (#lclCurrentPeriod, #snop_item, #lclfullfill_center, #lclDemandType, #lclLegacySSC, #lclDepo_wise_forecast, #cum_forecast, #draft_net_forecast, #forecast_consumed_by_sales, #net_offset_forecast);
END;
After deriving the net offset forecast it is going into while loop when the net offset forecast is less than zero and performing actions there and not coming up out with the data.
Need to improve the performance of the code to finish the loop and continue processing other data.

Update a table from another table

I have got 2 tables "animal_breeds" and "ztmp.ztmp_509810_anims_out". In "animals breed" every animal has key and breed name and percentage. Few animals might have 2 different breeds with different percentage. Now based on the animals key in "animals_breeds" i want to update "ztmp.ztmp_509810_anims_out"
i am using this code which i know is wrong
update ztmp.ztmp_509810_anims_out
set
alt_id1 = ab.breed
,alt_id2 = pcnt
,alt_id3 = ab.breed
,alt_id4 = pcnt
,alt_id5 = ab.breed
,alt_id6 = pcnt
,alt_id7 = ab.breed
,alt_id8 = pcnt
from animal_breeds ab
where ab.soc_code = ztmp_509810_anims_out.soc_code and ab.animals_key = ztmp_509810_anims_out.animals_key
and ab.soc_code = 'AUNDB';
could i use a for loop inside an update statement?
UPDATE ztmp.ztmp_509810_anims_out AS z
SET soc_code = q.soc_code,
animals_key = q.animals_key,
alt_id1 = breeds[1],
alt_id2 = pcnts[1],
alt_id3 = breeds[2],
alt_id4 = pcnts[2]
FROM (SELECT soc_code, animals_key,
array_agg(breed) breeds, array_agg(pcnt) pcnts
FROM animal_breeds
GROUP BY soc_code, animals_key
) q
WHERE z.soc_code = q.soc_code
AND z.animals_key = q.animals_key;
If there can be more than 2 breeds per animals_key, add breeds[3] and pcnts[3] and so on.

Count unknown variables from a table

I have a problem here... if I have a table with few repeated string results. I want to know the value am the ammount of each.
For example. A function return an unknown "letters" and with unknown quantities in quantity
Function () return Table end
Table ={'a','a','c','b','b','a',...}
And I want to get this.
table.a={'a','a','a'}
table.b={'b','b'}
table.c={'c'}
....
....
I have no clue how to solve it...
Write a function, which creates a hash map of these things:
function RepetitionCounter(tInput)
local tCounter = {}
for i, v in ipairs(tInput) do
tCounter[v] = (tCounter[v] or 0) + 1
end
return tCounter
end
which you'll use as follows:
local tData = {'a','a','c','b','b','a',...}
local tCounts = RepetitionCounter(tData)
and the table tCounts would be as follows:
tCounts.a = 3
tCounts.b = 2
tCounts.c = 1
Modifying the function above by just a little, you can get the desired output. Replace the following line:
tCounter[v] = (tCounter[v] or 0) + 1
with
if not tCounter[v] then
tCounter[v] = {}
else
table.insert(tCounter[v], v)
end

Entity Framework query with "not in"

I have a simple (well easy, not simple) query of "not in" on related tables.
SELECT CompetencyID, CompetencyName FROM Competency
WHERE (Deleted = 0) AND (CompanyID = 1) AND (CompetencyID NOT IN(SELECT CompetencyID
FROM CompetencyGroups WHERE (Deleted = 0) AND (CompanyID = 1) AND (GroupID = 1))) AND
(ParentID = 0) ORDER BY CompetencyName
In SQL I get the list that I need with remaining items not in the group. Now I want to bind this to a DataGrid using EF5.
I cannot get the query syntax properly (Using VB.net) to list the ID and the Name of the Competency...
Converted the provided c# answer to VB:
Dim excludeList = context.CompetencyGroups.Where(Function(x) x.Deleted = False And x.GroupID = GroupID).Select(Function(x) x.CompetencyID).ToArray
Dim results = context.Competencies.Where(Function(c) Not excludeList.Contains(c.CompetencyID) And c.Deleted = False And c.CompanyID = 1 And c.ParentID = 0).OrderBy(Function(c) c.CompetencyName)
GridView2.DataSource = results
GridView2.DataBind()
Hope this helps someone in the future. Took me about 4 hours to search, ask and convert...
Something like
var excludeList = context.CompetencyGroups.Where(x => x....).Select(x => x.CompetencyID).ToArray();
var results = context.Competency.Where(x => !excludeList.Contains(x.CompetencyID));
Update: Somebody else edited this and then someone rejected it, but the edit was a good one (to select the value)
If you need the Cast to make an array of Integers.
Dim excludeList = context.CompetencyGroups.Cast(Of CompentencyGroup).Select(Function(x) x.CompetencyID).ToArray()
Dim results = context.Competency.Where(Function(x) Not excludeList.Contains(x.CompetencyID))