How to write an equation in sql? - sql

I want to implement this equation in sql :
f(x) = f(a) + (f(b)-f(a)) * (x-a)/(b-a)
My input is as following:
What I tried was:
select ((select CosValue from CosineTable where Angle=70) +
((select CosValue from CosineTable where Angle=75) -
(select CosValue from CosineTable where Angle=70)) * (73-70) / (75-70)
from CosineTable;
It's showing me a syntax error.

You are missing one closing bracket )
Try this:
SELECT ( ( SELECT CosValue
FROM CosineTable
WHERE Angle = 70
) + ( ( SELECT CosValue
FROM CosineTable
WHERE Angle = 75
) - ( SELECT CosValue
FROM CosineTable
WHERE Angle = 70
) ) * ( 73 - 70 ) / ( 75 - 70 ) )
FROM CosineTable;
But it only works if you always get a single value back in your Subselects.

Assuming there is only one row per angle in your table, you query can be simplified by using a cross join:
select a70.cosvalue + (a75.cosvalue - a70.cosvalue) * (73-70) / (75-70))
from CosineTable a70
cross join cosinetable a75
where a70.angle = 70
and a75.angle = 75;

Related

How do i get result?

I need SUM of this result:
SELECT
ROUND(
(invoicesitems.pscost / invoicesitems.inmedunit -
AVG(ISNULL(mainexstock.peacecost,0)) / invoicesitems.inmedunit), 2)
*
CASE WHEN units.unitqty=3 THEN (invoicesitems.bigqty *
invoicesitems.inbigunit * invoicesitems.inmedunit) +
(invoicesitems.medqty * invoicesitems.inmedunit) +
invoicesitems.smallqty
ELSE (invoicesitems.bigqty * invoicesitems.inmedunit)
+ invoicesitems.smallqty
END AS PROFITS
FROM invoicesitems
INNER JOIN mainexstock ON mainexstock.pid = invoicesitems.pid
INNER JOIN units ON units.[uid] = invoicesitems.punits
WHERE invoicesitems.bid = 'B-0480580'
GROUP BY
invoicesitems.pid, invoicesitems.inbigunit,
invoicesitems.inmedunit, invoicesitems.bigqty,
invoicesitems.medqty, invoicesitems.smallqty,
invoicesitems.pscost, units.unitqty
You can use it as a CTE and get the sum. For example:
with a as (
-- your big query here
)
select sum(profits) as profits from a;

"Divide by zero error" error after join in sql server (that doesn't add any rows)

First time asking a question here, I apologize if I make any mistakes.
Here's the thing, I have the following query that works just fine:
select *
, [ENERGIA_NETA_SMEC_MWH]* [CONSUMO_DE_GAS_DAM3] * 9300 * 1000 / ( [CONSUMO_DE_GAS_DAM3] *9300 * 1000 + [CONSUMO_DE_GASOIL_M3] * 9211 + [CONSUMO_DE_FUELOIL_T] * 10500 *1000 ) as 'Energia generada GN MWh '
from tabla_parte tp
The issue "Divide by zero error encountered." appears when I add a left join:
select *
, [ENERGIA_NETA_SMEC_MWH]* [CONSUMO_DE_GAS_DAM3] * 9300 * 1000 / ( [CONSUMO_DE_GAS_DAM3] *9300 * 1000 + [CONSUMO_DE_GASOIL_M3] * 9211 + [CONSUMO_DE_FUELOIL_T] * 10500 *1000 ) as 'Energia generada GN MWh '
from tabla_parte tp
left join cog.dbo.ParteDetalle pd
on tp.ParteID = pd.ParteID and pd.ItemID = 46
I can't seems to find out why the error appears, since the left join shouldn't add any rows. I've verified with with the following queries:
select count(1) from tabla_parte tp
select count(1) from tabla_parte tp
left join cog.dbo.ParteDetalle pd
on tp.ParteID = pd.ParteID and pd.ItemID = 46
Both of them give me the same number.
Since the left join isn't adding any rows, why does the error appear after the join?
Thanks!
Use NULLIF() to prevent divide-by-zero:
select *,
( ([ENERGIA_NETA_SMEC_MWH] * [CONSUMO_DE_GAS_DAM3] * 9300 * 1000) /
NULLIF([CONSUMO_DE_GAS_DAM3] *9300 * 1000 + [CONSUMO_DE_GASOIL_M3] * 9211 + [CONSUMO_DE_FUELOIL_T] * 10500 *1000, 0)
) as [Energia generada GN MWh]
from tabla_parte tp;
If one or both the tables are views, then the problem could be occurring in the view.
The cause of your problem might be that SQL Server can re-arrange calculations, pushing them closer to where it reads the data -- and before filters are applied. This would be a particular issue if you have WHERE clauses somewhere (although these are not shown in your question).

select statement to list numbers in range

In DB2, I have this query to list numbers 1-x:
select level from SYSIBM.SYSDUMMY1 connect by level <= "some number"
But this maxes out due to SQL20450N Recursion limit exceeded within a hierarchical query.
How can I generate a list of numbers between 1 and x using a select statement when x is not known at runtime?
I found an answer based on this post:
WITH d AS
(SELECT LEVEL - 1 AS dig FROM SYSIBM.SYSDUMMY1 CONNECT BY LEVEL <= 10)
SELECT t1.n
FROM (SELECT (d7.dig * 1000000) +
(d6.dig * 100000) +
(d5.dig * 10000) +
(d4.dig * 1000) +
(d3.dig * 100) +
(d2.dig * 10) +
d1.dig AS n
FROM d d1
CROSS JOIN d d2
CROSS JOIN d d3
CROSS JOIN d d4
CROSS JOIN d d5
CROSS JOIN d d6
CROSS JOIN d d7) t1
JOIN ("subselect that returns desired value as i") t2
ON t1.n <= t2.i
ORDER BY t1.n
That's how I usually create lists:
For your example
numberlist (num) as
(
select min(1) from anytable
union all
select num + 1 from numberlist
where num <= x
)
I did something like this when I wanted a list of values to correspond with months:
with t1 (mon) as (
values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)
)
select * from t1
It seems a bit kludgy, but for a small list like 1-12, or even 1-50, it did what I needed it to.
It's nice to see someone else tagging their questions with DB2.
If you have any table known to have more than x rows, you can always do:
select * from (
select row_number() over () num
from my_big_table
) where num <= x
or, per bhamby's suggestion:
select row_number() over () num
from my_big_table
fetch first X rows only
For DB2 you can use recursive common table expressions (cf. IBM documentation on recursive CTE):
with max(num) as (
select 1 from sysibm.sysdummy1
)
,result (num) as (
select num from max
union ALL
select result.num+1
from result
where result.num<=100
)
select * from result;

Pearson Correlation SQL Server

I have two tables:
ID,YRMO,Counts
1,Dec 2013,4
1,Jan 2014,6
1,Feb 2014,7
2,Jan,2014,6
2,Feb,2014,8
ID,YRMO,Counts
1,Dec 2013,10
1,Jan 2014,8
1,March 2014,12
2,Jan 2014,6
2,Feb 2014,10
I want to find the pearson corelation coefficient for each sets of ID. There are about more than 200 different IDS.
Pearson correlation is a measure of the linear correlation (dependence) between two variables X and Y, giving a value between +1 and −1 inclusive
More can be found here :http://oreilly.com/catalog/transqlcook/chapter/ch08.html
at calculating correlation section
To calculate Pearson Correlation Coefficient; you need to first calculate Mean then standard daviation and then correlation coefficient as outlined below
1. Calculate Mean
insert into tab2 (tab1_id, mean)
select ID, sum([counts]) /
(select count(*) from tab1) as mean
from tab1
group by ID;
2. Calculate standard deviation
update tab2
set stddev = (
select sqrt(
sum([counts] * [counts]) /
(select count(*) from tab1)
- mean * mean
) stddev
from tab1
where tab1.ID = tab2.tab1_id
group by tab1.ID);
3. Finally Pearson Correlation Coefficient
select ID,
((sf.sum1 / (select count(*) from tab1)
- stats1.mean * stats2.mean
)
/ (stats1.stddev * stats2.stddev)) as PCC
from (
select r1.ID,
sum(r1.[counts] * r2.[counts]) as sum1
from tab1 r1
join tab1 r2
on r1.ID = r2.ID
group by r1.ID
) sf
join tab2 stats1
on stats1.tab1_id = sf.ID
join tab2 stats2
on stats2.tab1_id = sf.ID
Which on your posted data results in
See a demo fiddle here http://sqlfiddle.com/#!3/0da20/5
EDIT:
Well refined a bit. You can use the below function to get PCC but I am not getting exact same result as of your but rather getting 0.999996000000000 for ID = 1.
This could be a great entry point for you. You can refine the calculation further from here.
create function calculate_PCC(#id int)
returns decimal(16,15)
as
begin
declare #mean numeric(16,5);
declare #stddev numeric(16,5);
declare #count numeric(16,5);
declare #pcc numeric(16,12);
declare #store numeric(16,7);
select #count = CONVERT(numeric(16,5), count(case when Id=#id then 1 end)) from tab1;
select #mean = convert(numeric(16,5),sum([Counts])) / #count
from tab1 WHERE ID = #id;
select #store = (sum(counts * counts) / #count) from tab1 WHERE ID = #id;
set #stddev = sqrt(#store - (#mean * #mean));
set #pcc = ((#store - (#mean * #mean)) / (#stddev * #stddev));
return #pcc;
end
Call the function like
select db_name.dbo.calculate_PCC(1)
A Single-Pass Solution:
There are two flavors of the Pearson correlation coefficient, one for a Sample and one for an entire Population. These are simple, single-pass, and I believe, correct formulas for both:
-- Methods for calculating the two Pearson correlation coefficients
SELECT
-- For Population
(avg(x * y) - avg(x) * avg(y)) /
(sqrt(avg(x * x) - avg(x) * avg(x)) * sqrt(avg(y * y) - avg(y) * avg(y)))
AS correlation_coefficient_population,
-- For Sample
(count(*) * sum(x * y) - sum(x) * sum(y)) /
(sqrt(count(*) * sum(x * x) - sum(x) * sum(x)) * sqrt(count(*) * sum(y * y) - sum(y) * sum(y)))
AS correlation_coefficient_sample
FROM (
-- The following generates a table of sample data containing two columns with a luke-warm and tweakable correlation
-- y = x for 0 thru 99, y = x - 100 for 100 thru 199, etc. Execute it as a stand-alone to see for yourself
-- x and y are CAST as DECIMAL to avoid integer math, you should definitely do the same
-- Try TOP 100 or less for full correlation (y = x for all cases), TOP 200 for a PCC of 0.5, TOP 300 for one near 0.33, etc.
-- The superfluous "+ 0" is where you could apply various offsets to see that they have no effect on the results
SELECT TOP 200
CAST(ROW_NUMBER() OVER (ORDER BY [object_id]) - 1 + 0 AS DECIMAL) AS x,
CAST((ROW_NUMBER() OVER (ORDER BY [object_id]) - 1) % 100 AS DECIMAL) AS y
FROM sys.all_objects
) AS a
As I noted in the comments, you can try the example with TOP 100 or less for full correlation (y = x for all cases); TOP 200 yields correlations very near 0.5; TOP 300, around 0.33; etc. There is a place ("+ 0") to add an offset if you like; spoiler alert, it has no effect. Make sure you CAST your values as DECIMAL - integer math can significantly impact these calcs.

Counting in a sql query

So I'm having a table like
Now I need to get this packed into a datagridview when a choice is made in a combobox filled with the uv ='owner'.
If I make a choice of the uv eg MG. I get a list of all his files/dosno he worked in and the times he spend working on the file.
I do this with this query :
SELECT kbpres.uv,
dbo.doss.dosno,
SUM(dbo.kbpres.uur) AS somuur,
SUM(dbo.kbpres.minuut) AS somminuut,
CAST (( SUM(dbo.kbpres.uur) + SUM(dbo.kbpres.minuut) / 60 ) AS VARCHAR(4)
) +
'u ' + CAST (( SUM(dbo.kbpres.minuut) % 60 ) AS VARCHAR(2)) + 'm' AS
[derivedColumn],
doss.behdr
FROM dbo.kbpres
INNER JOIN dbo.doss
ON dbo.kbpres.ino = dbo.doss.ino
WHERE ( dbo.kbpres.uv LIKE #cboBeheerder )
GROUP BY kbpres.uv,
dbo.doss.dosno,
doss.behdr
(Allthough I would only like to group by UV, and have to add the dosno and behdr as well ??)
The problem is now, how can I count the correct cost, as it is per record different.
for MG it would be :
10 * 60 for dosno 88888
20 * 76 for 66666
60*10 + (28hours+10minutes * 10) + 10*2 for 12345
Any idea if this is even possible ??
SELECT dosno,
SUM(uur)*60 + SUM(minuut) AS Time,
(SUM(uur)*60 + SUM(minuut)) * cost AS TotalCost
FROM dbo.kbpres k
INNER JOIN dbo.doss d ON k.ino = d.ino
GROUP BY dosno,k.ino,d.ino,cost
WHERE k.uv = 2
As cost seems to be a function of uv and dosno try
SELECT dosno,SUM(Time) AS Time,SUM(TotalCost) AS TotalCost FROM
(
SELECT dosno,
uur*60 + minuut AS Time,
(uur*60 + minuut) * cost AS TotalCost
FROM dbo.kbpres k
INNER JOIN dbo.doss d ON k.ino = d.ino
GROUP BY dosno,k.ino,d.ino,cost
WHERE k.uv = 2
) t
GROUP BY dosno