Multiply values ​of two variables according to id - sql

I have a problem with the multiplication of two variables.
I have two sql statements with which I get the number of hours that an employee has worked during a specific month, and another statement to get the hourly cost that each employee has.
I must say that they are two different tables in the database.
What I would like is to multiply the hours of each employee by the hourly cost that employee has, and then add the results.
These two sentences work fine, if I do "print_r" I see the results that each employee has.
I guess I have to do it through the ID, but I don't know how to do it.
This is what I have so far, and I only get it to multiply the first person it finds.
$SumaHoras = $DB->Sql ("SELECT Id_Persona, CONCAT(SUM(Horas)* 3600)/36000000 as Hora FROM table1");
$SumaCosteHora = $DB->Sql("SELECT Id_CostPers, CONCAT(Coste_Hora) as Coste FROM table2");
$suma1 = [];
while($totalSumaHoras = $DB->Row($SumaHoras)){
$suma1 = $totalSumaHoras;
print_r($suma1);
}
$suma2 = [];
while($totalSumaCoste = $DB->Row($SumaCosteHora)){
$suma2 = $totalSumaCoste;
print_r($suma2);
}
$total4 = $suma1->Hora * $suma2->Coste;
I don't know if I explained myself well, but I appreciate any help you can offer me.

Your first line of code does not work - it generates errors - "The concat function requires 2 to 254 arguments." and then if you remove the CONCAT you get "Column 'table1.Id_Persona' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause." - as pointed out by #isamu
You should not use CONCAT for numbers - that returns a string - always use the correct Type for data.
To get all the information you require at once you need to use a JOIN see This article
E.g.
SELECT Id_Persona, t2.Coste_Hora * (SUM(t1.Horas) * 3600.0)/36000000.0
FROM table1 t1
INNER JOIN table2 t2 ON t1.Id_Persona = t2.Id_CostPers
group by Id_Persona, t2.Coste_Hora
I'm not sure why you are using that particular calculation but note I have appended .0 to those integer values to ensure that decimal calculation takes place - to explain what I mean try running these two lines of SQL
SELECT 10 * 3600/36000000;
SELECT 10 * 3600.0/36000000.0;

Related

Two Tables/Databases error: Only one expression can be specified in the select list when the subquery is not introduced with EXISTS

Using SQL Server I'm trying to multiply two columns of a distinct part number using 2 tables and 2 databases but it gives this error:
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
This SQL joins two tables in different databases and show the Final Part Number (FinalPartNo) for a bumper and the ancillary parts that it needs to put it together (bolts, brackets etc.)
Query:
SELECT
tb_1.FinalPartNo,
tb_1.SubPartType,
tb_1.SubPart,
tb_1.FinalItemSubPartQuantity,
tb_2.PurchasedOrMfg,
tb_2.SalesWeek1,
tb_2.SalesWeek2
FROM [009Reports].[dbo].[ANC Parts] tb_1
JOIN [555].[cache].[PurchasingSupplyChainNeeds] tb_2 ON tb_1.FinalPartNo = tb_2.ItemNo
So it displays this:
If you look at the table and to siplify things, I highlighted 3 part numbers that all use the same SubPart. Two of them use 4 of the FinalSubPartQuantity and one uses 2 in the "install" step. For SalesWeek1 of the highlighted in the image, they sold two of the FinalPartNo which requires 4 FinalSubPartQuantity and had two sales so that totals 8 needed for that week. I don't need the FinalPartNo but added that to show that it's multiple FinalPartNo with the same subpart.
Trying to figure to sum them up with a totals column for each SubPart for that week (for 52 weeks, just showing 2).
In this example, 03CSFY-0500350 for SalesWeek1 could total 150 having it on
multiple FinalPartNo and multiple steps (Fabricate, Assembly, Install).
So, I tried a subquery to make the SubPart distinct and multiply the FinalSubPartQuantity x SalesWeek1 for TotalSalesWeek1 but getting error. Trying to figure out syntax.
SELECT
tb_1.SubPart,
tb_1.FinalItemSubPartQuantity,
TotalSalesWeek1 = (SELECT DISTINCT(tb_1.SubPart),
tb_1.FinalItemSubPartQuantity * tb_2.SalesWeek1),
TotalSalesWeek2 = (SELECT DISTINCT(tb_1.SubPart),
tb_1.FinalItemSubPartQuantity * tb_2.SalesWeek2)
FROM [009Reports].[dbo].[ANC Parts] tb_1
JOIN [555].[cache].[PurchasingSupplyChainNeeds] tb_2 ON tb_1.FinalPartNo = tb_2.ItemNo
I'm just trying to display:
SubPart/FinalSubPartQuantity/TotalSalesWk1/TotalSalesWk2/TotalSalesWk3/ to week 52. So it just shows the sub part, sum of all the FinalSubPartQuantity amounts for that part for all the different FinalPartNo's and the total sales FinalItemPartQuantity * SalesWeek1, 2, 3...
summarize: subpart and how many sold of that part that week.
You can't set the TotalSalesWeek1 to two columns (DISTINCT(tb_1.SubPart) and tb_1.FinalItemSubPartQuantity * tb_2.SalesWeek1).
I would suggest something like the following
SELECT
tb_1.SubPart,
SUM(tb_1.FinalItemSubPartQuantity) FinalItemSubPartQuantity,
SUM(tb_1.FinalItemSubPartQuantity * tb_2.SalesWeek1) TotalSalesWeek1
SUM(tb_1.FinalItemSubPartQuantity * tb_2.SalesWeek2) TotalSalesWeek2
FROM [009Reports].[dbo].[ANC Parts] tb_1
JOIN [555].[cache].[PurchasingSupplyChainNeeds] tb_2 ON tb_1.FinalPartNo = tb_2.ItemNo
GROUP BY tb_1.SubPart
The GROUP BY tb_1.SubPart at the end says you want each unique SubPart on a row, the SUMs in the SELECT explain that you want those values summed for each group.

How to calculate a bank's deposit growth from one call report to the next, as a percentage?

I downloaded the entire FDIC bank call reports dataset, and uploaded it to BigQuery.
The table I currently have looks like this:
What I am trying to accomplish is adding a column showing the deposit growth rate since the last quarter for each bank:
Note:The first reporting date for each bank (e.g. 19921231) will not have a "Quarterly Deposit Growth". Hence the two empty cells for the two banks.
I would like to know if a bank is increasing or decreasing its deposits each quarter/call report (viewed as a percentage).
e.g. "On their last call report (19921231)First National Bank had deposits of 456789 (in 1000's). In their next call report (19930331)First National bank had deposits of 567890 (in 1000's). What is the percentage increase (or decrease) in deposits"?
This "_%_Change_in_Deposits" column would be displayed as a new column.
This is the code I have written so far:
select
SFRNLL.repdte, SFRNLL.cert, SFRNLL.name, SFRNLL.city, SFRNLL.county, SFRNLL.stalp, SFRNLL.specgrp AS `Loan_Specialization`, SFRNLL.lnreres as `_1_to_4_Residential_Loans`, AL.dep as `Deposits`, AL.lnlsnet as `loans_and_leases`,
IEEE_DIVIDE(SFRNLL.lnreres, AL.lnlsnet) as SFR2TotalLoanRatio
FROM usa_fdic_call_reports_1992.All_Reports_19921231_1_4_Family_Residential_Net_Loans_and_Leases as SFRNLL
JOIN usa_fdic_call_reports_1992.All_Reports_19921231_Assets_and_Liabilities as AL
ON SFRNLL.cert = AL.cert
where SFRNLL.specgrp = 4 and IEEE_DIVIDE(SFRNLL.lnreres, AL.lnlsnet) <= 0.10
UNION ALL
select
SFRNLL.repdte, SFRNLL.cert, SFRNLL.name, SFRNLL.city, SFRNLL.county, SFRNLL.stalp, SFRNLL.specgrp AS `Loan_Specialization`, SFRNLL.lnreres as `_1_to_4_Residential_Loans`, AL.dep as `Deposits`, AL.lnlsnet as `loans_and_leases`,
IEEE_DIVIDE(SFRNLL.lnreres, AL.lnlsnet) as SFR2TotalLoanRatio
FROM usa_fdic_call_reports_1993.All_Reports_19930331_1_4_Family_Residential_Net_Loans_and_Leases as SFRNLL
JOIN usa_fdic_call_reports_1993.All_Reports_19930331_Assets_and_Liabilities as AL
ON SFRNLL.cert = AL.cert
where SFRNLL.specgrp = 4 and IEEE_DIVIDE(SFRNLL.lnreres, AL.lnlsnet) <= 0.10
The table looks like this:
Additional notes:
I would also like to view the last column (SFR2TotalLoansRatio) as a percentage.
This code runs correctly, however, previously I was getting a "division by zero" error when attempting to run 50,000 rows (1992 to the present).
Addressing each of your question individually.
First) Retrieving SFR2TotalLoanRatio as percentage, I assume you want to see 9.988% instead of 0.0988 in your results. Currently, in BigQuery you can achieve this by casting the field into a STRING then, concatenating the % sign. Below there is an example with sample data:
WITH data as (
SELECT 0.0123 as percentage UNION ALL
SELECT 0.0999 as percentage UNION ALL
SELECT 0.3456 as percentage
)
SELECT CONCAT(CAST(percentage*100 as String),"%") as formatted_percentage FROM data
And the output,
Row formatted_percentage
1 1.23%
2 9.99%
3 34.56%
Second) Regarding your question about the division by zero error. I am assuming IEEE_DIVIDE(arg1,arg2) is a function to perform the division, in which arg1 is the divisor and arg2 is the dividend. Therefore, I would adivse your to explore your data in order to figured out which records have divisor equals to zero. After gathering these results, you can determine what to do with them. In case you decide to discard them you can simply add within your WHERE statement in each of your JOINs: AL.lnlsnet = 0. On the other hand, you can also modify the records where lnlsnet = 0 using a CASE WHEN or IF statements.
UPDATE:
In order to add this piece of code your query, you u have to wrap your code within a temporary table. Then, I will make two adjustments, first a temporary function in order to calculate the percentage and format it with the % sign. Second, retrieving the previous number of deposits to calculate the desired percentage. I am also assuming that cert is the individual id for each of the bank's clients. The modifications will be as follows:
#the following function MUST be the first thing within your query
CREATE TEMP FUNCTION percent(dep INT64, prev_dep INT64) AS (
Concat(Cast((dep-prev_dep)/prev_dep*100 AS STRING), "%")
);
#followed by the query you have created so far as a temporary table, notice the the comma I added after the last parentheses
WITH data AS(
#your query
),
#within this second part you need to select all the columns from data, and LAG function will be used to retrieve the previous number of deposits for each client
data_2 as (
SELECT repdte, cert, name, city, county, stalp, Loan_Specialization, _1_to_4_Residential_Loans,Deposits, loans_and_leases, SFR2TotalLoanRatio,
CASE WHEN cert = lag(cert) OVER (PARTITION BY id ORDER BY d) THEN lag(Deposits) OVER (PARTITION BY id ORDER BY id) ELSE NULL END AS prev_dep FROM data
)
SELECT repdte, cert, name, city, county, stalp, Loan_Specialization, _1_to_4_Residential_Loans,Deposits, loans_and_leases, SFR2TotalLoanRatio, percent(Deposits,prev_dep) as dept_growth_rate FROM data_2
Note that the built-in function LAG is used together with CASE WHEN in order to retrieve the previous amount of deposits per client.

How to resolve a Left Join sub-query error?

In MS-Access I'm trying to join three tables. The third table is created from a sub-query designed to aggregate dates because I don't want multiple records per day when aligned with the first table.
When I entered the left join sub-query, I got this error:
The field is too small to accept the amount of data you attempted to
add. Try inserting or pasting less data.
I've run the sub-query separately and it returns about 19,000 records. Which is quite smaller than the actual table. If I use the actual table, the query works just fine, but it includes the duplicate records when there is more than one entry per day on the third table.
SELECT
SUM([ACD Calls]),
(SUM([Avg ACD Time]*[ACD Calls])/SUM([ACD Calls]))/86400,
(SUM([Avg ACW Time]*[ACD Calls])/SUM([ACD Calls]))/86400,
((SUM([Hold Time])/SUM([ACD Calls])))/86400,
((SUM([Avg ACD Time]*[ACD Calls])
+ SUM([Avg ACW Time]*[ACD Calls]))/SUM([ACD Calls]))/86400,
SUM([Time Adhering])/SUM([Total Time Scheduled]),
SUM([SS])/SUM([SO])
FROM
(
(
[GroupSumDaily]
LEFT JOIN Adherence_WKLY ON (GroupSumDaily.[Day] = Adherence_WKLY.[Day])
AND (GroupSumDaily.Agent = Adherence_WKLY.Agent)
)
LEFT JOIN
(
SELECT Evaluation_List.[Agent],
Evaluation_List.Recording_Date,
SUM(Evaluation_List.[Score]) as SS,
SUM(Evaluation_List.[Out of]) as SO
From Evaluation_List
Group By Evaluation_List.[Recording_Date],
Evaluation_list.[Agent]
)
as Evals ON (GroupSumDaily.[Day] = Evals.[Recording_Date])
AND (GroupSumDaily.Agent = Evals.Agent)
)
WHERE
(
[GroupSumDaily].[Agent] = "LastName FirstName"
AND Month([GroupSumDaily].[Day]) =1
AND Year([GroupSumDaily].[Day]) =2018
AND [GroupSumDaily].[Day] > #2/23/2015#
)
It looks like you don't have a "main" table to query from.
I'd try removing the first two open brackets after the FROM statement (and their equivalent closing brackets.)
If that doesn't fix it, try moving the whole sub-query into a separate query and selecting from the results...
It turns out the subquery fields are automatically limited to 50 characters and this was the root of the problem. When I limited the return to LEFT([Agent], 50), the error disappeared. Is there a way to set character length is a subquery field?
The other odd things is, none of my fields were actually over 50 characters... when I ran Select [Agent] Where LEN([Agent]) >= 50, it returned only 1 records, and it was the "NEW" blank record from the bottom. I confirmed that it completely blank, with no spaces or tabs. Very confusing.

How to use aggregate function to filter a dataset in ssrs 2008

I have a matrix in ssrs2008 like below:
GroupName Zone CompletedVolume
Cancer 1 7
Tunnel 1 10
Surgery 1 64
ComplatedVolume value is coming by a specific expression <<expr>>, which is equal to: [Max(CVolume)]
This matrix is filled by a stored procedure that I am not supposed to change if possible. What I need to do is that not to show the data whose CompletedVolume is <= 50. I tried to go to tablix properties and add a filter like [Max(Q9Volume)] >= 50, but when I try to run the report it says that aggregate functions cannot be used in dataset filters or data region filters. How can I fix this as easy as possible?
Note that adding a where clause in sql query would not solve this issue since there are many other tables use the same SP and they need the data where CompletedVolume <= 50. Any help would be appreciated.
EDIT: I am trying to have the max(Q9Volume) value on SP, but something happening I have never seen before. The query is like:
Select r.* from (select * from results1 union select * from results2) r
left outer join procedures p on r.pid = p.id
The interesting this is there are some columns I see that does not included by neither results1/results2 nor procedures tables when I run the query. For example, there is no column like Q9Volume in the tables (result1, result2 and procedures), however when I run the query I see the columns on the output! How is that possible?
You can set the Row hidden property to True when [Max(CVolume)] is less or equal than 50.
Select the row and go to Row Visibility
Select Show or Hide based on an expression option and use this expression:
=IIF(
Max(Fields!Q9Volume.Value)<=50,
True,False
)
It will show something like this:
Note maximum value for Cancer and Tunnel are 7 and 10 respectively, so
they will be hidden if you apply the above expression.
Let me know if this helps.

Invalid number while comparing string to number oracle

Hello I am currently involved in a project that is running for over 2 years, and yesterday, we started to face following issue:
One query that was always used and ran at least 20.000 every single day, yesterday fom nothing started to return invalid number error.
ORA-01722: invalid number
select orq.rt_id, orec.* from orderrec orec
join order_header oh on (oh.order_code = orec.ordernumber and oh.page = orec.pagenumber)
left join order_request orq on oh.orq_id = orq.orq_id
where ordernumber=? and pagenumber=? and state < 100
the problematic part is:
oh.order_code = orec.ordernumber
order_code is a string
ordernumber is a number
As this is would give a high impact on clients production I've change the equal comparison to a like find query bellow. After this change process started to work again without issue.
select orq.rt_id, orec.* from orderrec orec join order_header oh on (oh.order_code like orec.ordernumber and oh.page = orec.pagenumber) left join order_request orq on oh.orq_id = orq.orq_id
where ordernumber=? and pagenumber=? and state < 10
This query is a XML file used with a java program.
My doubt is why this would have happend?
I would check to see if the ORDER_CODE field, which you say is a string, contains any new values with non-digit characters (0-9) as that would be my guess as to the cause.
Even though your ORDER_CODE field is a string, when you join that field with a number field, Oracle will attempt to convert that string to a number (implicitly). You might as well be using the to_number() function on the ORDER_CODE field, because that is how it's actually being processed.
For instance, this query:
select *
from tablea a
join tableb b
on a.order_code = b.ordernumber
Will not return an error if ORDER_CODE contains values with only digits (0-9) and no letters.
But if it does contain at least one such value, boom, you get the error you describe.
It is true that you can use LIKE to avoid the error, but it will be unable to match rows where the ORDER_CODE has letters. Notice how in this example http://sqlfiddle.com/#!4/f00f91/1/0 '9A' won't match with 9, whereas '8' does match with 8.
The answer in a nutshell is that because you're joining two fields of a different format, one a string, one a number, a conversion from the string to a number is implied. And obviously, when the string contains letters such as A, B, C, etc. it will be unable to do the conversion and so it will give you that error.
You can run this query to find the "problem values", my guess is that whatever rows are returned were recently inserted, causing the error:
Fiddle:
http://sqlfiddle.com/#!4/f5b55/1/0
select *
from order_header
where regexp_like(order_code, '[^0-9]')