Calculating weighted Average From DB - sql

Hi every one.
I have a DB shown in the following picture.
enter image description here
Every season, every personnel could have one or more posts and every post is in a specific unit. My question is how to calculate weighted AVG for every personnel in each related posts (note that we have two types of criteria where ct.ID = 1 OR 2). I did something as below
select r.EvaluaTEDID,r.PostID, Avg(r.FirstScore*iif(ct.id=1,p.COMCrtWeight/100,0))+
Avg(r.FirstScore*iif(ct.id=2,p.PROCrtWeight/100,0)) as 'AVG'
from results r
inner join post p on r.PostID = p.ID
inner join job j on p.JobID = j.ID
inner join subcrt sc on r.SubCrtID = sc.ID
inner join Crt c on sc.CrtID = c.ID
inner join CrtType ct on c.CrtTypeID = ct.ID
where r.SeasonID = 4 and j.UnitID = 3068
group by r.EvaluaTEDID, r.PostID
but MSSQLS showed 46 which is the weighted average of all records for personnel with ID=8. The desired answer should be 87 (36+51)
COMCrtWeight=40,PROCrtWeight=60
ct.ID for SubCID=6 is 2 and ct.ID for SubCID=1 & 4 is 1
seasonID - EvaluaTEDID - SubCID - PostID - Score
4 ------------ 8 ------------------ 6 ----------- 26 ------ 90
4 ------------ 8 ------------------ 1 ----------- 26 ------ 90
4 ------------ 8 ------------------ 4 ----------- 26 ------ 90
I also did something like this:
select EvaluaTEDID, sum(WeightedSum) from
(select r.EvaluaTEDID,r.PostID,
avg(r.FirstScore*iif(ct.id=1,p.COMCrtWeight/100,p.PROCrtWeight/100))
as WeightedSum from results r
inner join post p on r.PostID = p.ID
inner join job j on p.JobID = j.ID
inner join subcrt sc on r.SubCrtID = sc.ID
inner join Crt c on sc.CrtID = c.ID
inner join CrtType ct on c.CrtTypeID = ct.ID
where r.SeasonID = 4 and j.UnitID = 3068
group by ct.id, r.EvaluaTEDID, r.PostID)
group by EvaluaTEDID
Buy I got syntax error.
Could you please help.
Thanks in advance.

Related

SQL Queue to get workload in 2 weeks [SQL Server]

Currently, the queue shows me the workload of products in a oven and for product which are in the oven too, but actually for some hours in a test outside of the oven.
I count the h with "gesamt" for each product -> this show me how Long they stay already in the oven. Mostly the products stay 1000h in the oven its defined in "Zielgröße" in the db.
What I want is that the queue should show me the workload of the oven for the next 2 weeks as a prediction (336h). Thats all "gesamt" which is over "Zielgröße" (mostly 1000) not shown in the queue maybe handled in a temporary table or whatever.
Is it possible to handle this in Micrososft SQL Server?
Here is the code:
SELECT TesterID,Name, TesterNr, COUNT(Name) as Anzahl, gesamt FROM
(SELECT AllgemeineAngaben.QualiID,
Bezeichnung,
AnzModule,
Tester.Name, TesterNr,
Testname,
v_gesamtBerechnungLaufend.TestaufstellungID,
lastRO,
gesamt,
v_gesamtBerechnungLaufend.Einheit,
v_gesamtBerechnungLaufend.PlanID,
v_gesamtBerechnungLaufend.TesterID
FROM DB.dbo.AllgemeineAngaben inner join
DB.dbo.v_gesamtBerechnungLaufend on
AllgemeineAngaben.QualiID = v_gesamtBerechnungLaufend.QualiID inner join
DB.dbo.Tester on
Tester.TesterID = v_gesamtBerechnungLaufend.TesterID inner join
DB.dbo.Testaufstellung on
Testaufstellung.TestaufstellungID = v_gesamtBerechnungLaufend.TestaufstellungID inner join
DB.dbo.Testnamen on Testnamen.TestnameID = Testaufstellung.TestnameID
Where Tester.Name = 'KPS02'
UNION ALL
SELECT AllgemeineAngaben.QualiID,
Bezeichnung, AnzModule, Tester.Name, TesterNr,
Testname,
Testaufstellung.TestaufstellungID,
v_gesamtBerechnung.gesamt as lastRO,
v_gesamtBerechnung.gesamt,
v_gesamtBerechnung.Einheit,
v_gesamtBerechnung.PlanID,
v_gesamtBerechnung.TesterID
FROM DB.dbo.AllgemeineAngaben inner join
DB.dbo.v_gesamtBerechnung on
AllgemeineAngaben.QualiID = v_gesamtBerechnung.QualiID inner join
DB.dbo.Tester on
Tester.TesterID = v_gesamtBerechnung.TesterID inner join
DB.dbo.Testaufstellung on
Testaufstellung.TestaufstellungID = v_gesamtBerechnung.TestaufstellungID inner join
DB.dbo.Testnamen on Testnamen.TestnameID = Testaufstellung.TestnameID
WHERE Testaufstellung.fertig ='0'
AND Testaufstellung.aktiv ='1'
AND Testaufstellung.Zielgröße > v_gesamtBerechnung.gesamt
AND Tester.Name = 'KPS02'
AND v_gesamtBerechnung.TestaufstellungID not in (Select TestaufstellungID from DB.dbo.v_gesamtBerechnungLaufend)) x
group by TesterID, Name, TesterNr, gesamt
Here the table to show in an example what I want
actual workload
TesterID Name TesterNr Anzahl gesamt
-------------- ------- ---------- ----------- -----------
Product1 8 KPS02 2 1 209
Product2 8 KPS02 2 1 216
Product3 8 KPS02 2 1 816
Product4 8 KPS02 2 1 835
workload in 2 weeks
TesterID Name TesterNr Anzahl gesamt
-------------- ------- ---------- ----------- -----------
Product1 8 KPS02 2 1 545
Product2 8 KPS02 2 1 552
the last recors are over 1000 Zielgröße, so just dont show them in the prediction queue
Product3 8 KPS02 2 1 1152
Product4 8 KPS02 2 1 1171
I hope you guys can follow me. Thanks for your help.
I'll edit this answer until it's solved, but here's my first attempt:
SELECT TesterID,Name, TesterNr, COUNT(Name) as Anzahl, gesamt + 336 as gesamt
FROM
(SELECT AllgemeineAngaben.QualiID,
Bezeichnung,
AnzModule,
Tester.Name, TesterNr,
Testname,
v_gesamtBerechnungLaufend.TestaufstellungID,
lastRO,
gesamt,
v_gesamtBerechnungLaufend.Einheit,
v_gesamtBerechnungLaufend.PlanID,
v_gesamtBerechnungLaufend.TesterID
FROM DB.dbo.AllgemeineAngaben inner join
DB.dbo.v_gesamtBerechnungLaufend on
AllgemeineAngaben.QualiID = v_gesamtBerechnungLaufend.QualiID inner join
DB.dbo.Tester on
Tester.TesterID = v_gesamtBerechnungLaufend.TesterID inner join
DB.dbo.Testaufstellung on
Testaufstellung.TestaufstellungID = v_gesamtBerechnungLaufend.TestaufstellungID inner join
DB.dbo.Testnamen on Testnamen.TestnameID = Testaufstellung.TestnameID
Where Tester.Name = 'KPS02'
UNION ALL
SELECT AllgemeineAngaben.QualiID,
Bezeichnung, AnzModule, Tester.Name, TesterNr,
Testname,
Testaufstellung.TestaufstellungID,
v_gesamtBerechnung.gesamt as lastRO,
v_gesamtBerechnung.gesamt,
v_gesamtBerechnung.Einheit,
v_gesamtBerechnung.PlanID,
v_gesamtBerechnung.TesterID
FROM DB.dbo.AllgemeineAngaben inner join
DB.dbo.v_gesamtBerechnung on
AllgemeineAngaben.QualiID = v_gesamtBerechnung.QualiID inner join
DB.dbo.Tester on
Tester.TesterID = v_gesamtBerechnung.TesterID inner join
DB.dbo.Testaufstellung on
Testaufstellung.TestaufstellungID = v_gesamtBerechnung.TestaufstellungID inner join
DB.dbo.Testnamen on Testnamen.TestnameID = Testaufstellung.TestnameID
WHERE Testaufstellung.fertig ='0'
AND Testaufstellung.aktiv ='1'
AND Testaufstellung.Zielgröße > v_gesamtBerechnung.gesamt
AND Tester.Name = 'KPS02'
AND v_gesamtBerechnung.TestaufstellungID not in (Select TestaufstellungID from DB.dbo.v_gesamtBerechnungLaufend)) x
group by TesterID, Name, TesterNr, gesamt
) A
WHERE gesamt + 336 < 1000
It seems to me like all you need to do is add 336 to the current values and then filter out anything less than 1000.

Count string values From row using sql?

I have a SQL query in which I am using INNER JOIN but I have to calculate the string values ERROR, OK and their total from column d.sd_figure.
This is my SQL query
SELECT
count(d.sd_figure = 'ERROR') AS error,
count(d.sd_figure = 'OK') AS OK count,
count(*) AS total,
m.contr_num, bu.buyer_name,
m.S_remarks, cr.contr_name, br.brand_name,
m.S_date, c.colour_name, s.size_name,
mn.manu_name
FROM
Scanning_M m
INNER JOIN
colour c ON m.color_id = c.colour_id
INNER JOIN
Buyer bu ON m.buyer_id = bu.Byer_ID
INNER JOIN
Scanning_D d ON m.S_id = d.S_id
INNER JOIN
Brand br ON m.Brand_id = br.Brand_id
INNER JOIN
Contract cr ON m.Contr_num = cr.Contr_id
INNER JOIN
Size s ON m.Size_id = s.Size_id
INNER JOIN
Manufacturer mn ON m.Manu_id = mn.manu_id
WHERE
m.S_date BETWEEN '2016-01-13' AND '2016-01-13'
I also want to add count of 'error' , 'OK' and 'Total' too error is in this line
SELECT
count(d.sd_figure = 'ERROR') AS error,
count(d.sd_figure = 'OK') as OK count,
count(*) as total ,
I tried many solution butt returned group by not found etc
SAMPLE DATA DEMANDED FOR d.sd_figure
S_id sd_res sd_figure sd_datetime sd_id
4 456456 ERROR 2016-01-09 03:11:07.000 1
4 456456 ERROR 2016-01-09 03:11:07.000 2
4 456456 ERROR 2016-01-09 03:11:07.000 3
6 123 ERROR 2016-01-09 10:54:47.000 22
6 123 ERROR 2016-01-09 10:54:47.000 23
6 123 ERROR 2016-01-09 10:54:47.000 24
6 123 ERROR 2016-01-09 10:54:48.000 25
6 123 ERROR 2016-01-09 10:54:48.000 26
Untested, but should be something like this:
SELECT sum(CASE WHEN d.sd_figure = 'ERROR' THEN 1 ELSE 0 END) AS error
,sum(CASE WHEN d.sd_figure = 'OK' THEN 1 ELSE 0 END) AS [OK count]
,count(*) AS total
,m.contr_num
,bu.buyer_name
,m.S_remarks
,cr.contr_name
,br.brand_name
,m.S_date
,c.colour_name
,s.size_name
,mn.manu_name
FROM Scanning_M m
INNER JOIN colour c ON m.color_id = c.colour_id
INNER JOIN Buyer bu ON m.buyer_id = bu.Byer_ID
INNER JOIN Scanning_D d ON m.S_id = d.S_id
INNER JOIN Brand br ON m.Brand_id = br.Brand_id
INNER JOIN Contract cr ON m.Contr_num = cr.Contr_id
INNER JOIN Size s ON m.Size_id = s.Size_id
INNER JOIN Manufacturer mn ON m.Manu_id = mn.manu_id
WHERE m.S_date BETWEEN '2016-01-13' AND '2016-01-13'
GROUP BY m.contr_num
,bu.buyer_name
,m.S_remarks
,cr.contr_name
,br.brand_name
,m.S_date
,c.colour_name
,s.size_name
,mn.manu_name

Fetch Max Value

TABLE Laptop_Shift_Departments
id Laptop_ID Curr_department Pre_Department
-----|----------|-----------------|----------------
9 71 4 3
10 68 4 3
11 71 5 4
12 68 5 4
User only search PO Number and against this PO_Num there are 2 laptops (Laptop_ID)
Above is my table now i want to get MAX value Against this laptop_ID ID
I have tried this:
SELECT LD.ID AS Laptop_ID,ld.GulfITBarcode,po.ID as PO_ID,PO.PO_Number as PO_Number,D.Department,
D.ID as Crr_DepID1,d2.Department,D2.ID as Pre_DepID2
FROM PO_PURCHASEORDER PO
INNER JOIN PO_Laptop_Master LM
ON LM.PO_ID = PO.ID
INNER JOIN PO_LaptopDetail LD
ON LD.LapTop_Master_ID = LM.ID
INNER JOIN Laptop_Shift_Departments DP
ON DP.Laptop_Detail_ID = LD.ID
inner join Laptop_Departments d
on d.ID = DP.Current_Dep_ID
inner join Laptop_Departments d2
on d2.ID = DP.Previous_Dep_ID
WHERE PO_NUMBER = '5258'
AND
LD.ID IN (select Max(cSh.id) from Laptop_Shift_Departments cSh)
But it is not working
MY output should be like this:
id Laptop_ID Curr_department Pre_Department
-----|----------|-----------------|----------------
11 71 5 4
12 68 5 4
You'll want to use the 'Group By' function at the end of the fields you want to group by and the 'Max' function in the Select on the columns you want the 'Max' (or 'Min' or 'Avg'). Should look something like this:
SELECT
LD.ID AS Laptop_ID
,ld.GulfITBarcode
,po.ID as PO_ID
,PO.PO_Number as PO_Number
,D.Department
,MAX(D.ID) as Crr_DepID1
,d2.Department
,MAX(D2.ID) as Pre_DepID2
FROM PO_PURCHASEORDER PO
INNER JOIN PO_Laptop_Master LM
ON LM.PO_ID = PO.ID
INNER JOIN PO_LaptopDetail LD
ON LD.LapTop_Master_ID = LM.ID
INNER JOIN Laptop_Shift_Departments DP
ON DP.Laptop_Detail_ID = LD.ID
inner join Laptop_Departments d
on d.ID = DP.Current_Dep_ID
inner join Laptop_Departments d2
on d2.ID = DP.Previous_Dep_ID
WHERE PO_NUMBER = '5258'
AND LD.ID IN (select Max(cSh.id) from Laptop_Shift_Departments cSh)
AND DP.Current_Dep_ID = 5
GROUP BY
LD.ID
,ld.GulfITBarcode
,po.ID
,PO.PO_Number
,D.Department
,d2.Department
(Having not seen the table structure I'm not sure as to the rest of the query. Hope this helps.)

extend SQL result - add row if not exist

At the moment I have a query like this:
SELECT d.[status]
,d.[PGID] as PGID
,pg.[nvarchar5] as PGName
,COUNT(d.[nvarchar10])
FROM
[content].[dbo].[USRData] d
INNER JOIN
[content].[dbo].[USRData] pg on d.[PGID] = pg.[tp_ID]
WHERE d.CatId = '12345'
AND d.[nvarchar10] is not null
AND d.[isActive] = 1
AND pg.[CatId] = '64521'
GROUP BY
pg.[nvarchar5]
,d.[status]
ORDER BY PGName
This is the result (just a fictive example):
status PGID PGName Total
--------- ------- --------- ---------
active 10 HR 120
deleted 10 HR 5
new 10 HR 10
active 15 IT 10
new 15 IT 40
deleted 32 FI 12
new 32 FI 30
I need a query so the result should be like this:
status PGID PGName Total
--------- ------- --------- ---------
active 10 HR 120
deleted 10 HR 5
new 10 HR 10
active 15 IT 10
deleted 15 IT 0
new 15 IT 40
active 32 FI 0
deleted 32 FI 12
new 32 FI 30
The difference is: I want for every PG a list of total for every possible status, even if it doesn't exist. If it doesn't exist I need a row like for example "deleted 15 IT 0"
I need to now every total of a possible status for every PG.
What do I need to change?
Edit:
More information
In the current query the inner join is on PGID and not status
about my table, an example: use array/variable in sql-query
Update 2:
with this query I get better results, only the total is not correct...
SELECT stat.status
,d.[PGID] as PGID
,pg.[nvarchar5] as PGName
,COUNT(d.[nvarchar10])
FROM
(select distinct [status]
from [content].[dbo].[USRData]
where CatId = '1234') stat cross Join
[content].[dbo].[USRData] d INNER JOIN
[content].[dbo].[USRData] pg on d.[PGID] = pg.[tp_ID]
where d.CatId = '1234'
AND d.[nvarchar10] is not null
AND stat.status is not null
AND d.[isActive] = 1
AND pg.[CatId] = '64521'
group by stat.status,
pg.[nvarchar5],
d.[PGID]
order by PGName
With my example as above, this is what I get:
status PGID PGName Total
--------- ------- --------- ---------
active 10 HR 135
deleted 10 HR 135
new 10 HR 135
active 15 IT 50
deleted 15 IT 50
new 15 IT 50
active 32 FI 42
deleted 32 FI 42
new 32 FI 42
I get the total for every PGName. How can I get the total for every PGName/status?
You do this by creating the cartesian product of status and PGID. You can get this from the table your are using. In this case, I think the query is:
SELECT sall.[status], pgall.[PGID] as PGID, pg.[nvarchar5] as PGName, COUNT(d.[nvarchar10])
FROM (select distinct status from [content].[dbo].[USRData]) sall cross join
(select distinct pgid from [content].[dbo].[USRData]) pgall left outer join
[content].[dbo].[USRData] d
on d.status = sall.status left outer join
[content].[dbo].[USRData] pg
on pg.[PGID] = pgall.[tp_ID]
where d.CatId = '12345' AND
d.[nvarchar10] is not null AND
d.[isActive] = 1 AND
pg.[CatId] = '64521'
group by pgall.[nvarchar5], sall.[status]
order by PGName
I'm not 100% sure this is what you want, because you are taking PGID and status from the d table -- I don't fully understand the self join here.
Inner Join is issue in you query, it excludes Roles who don't have users, instead use Left join
SELECT d.[status]
,d.[PGID] as PGID
,pg.[nvarchar5] as PGName
,COUNT(d.[nvarchar10])
FROM [content].[dbo].[USRData] d Left JOIN
[content].[dbo].[USRData] pg on d.[PGID] = pg.[tp_ID]
where d.CatId = '12345'
AND d.[nvarchar10] is not null
AND d.[isActive] = 1
AND pg.[CatId] = '64521'
group by pg.[nvarchar5], d.[status]
order by PGName

ms access max count

Here is my query:
SELECT Count(*) AS CountOfJoker, tblPrediction.GameID
FROM (tblUser INNER JOIN (tblPool INNER JOIN tblUserPool ON tblPool.PoolID = tblUserPool.PoolID) ON tblUser.UserID = tblUserPool.UserID) INNER JOIN (tblResult INNER JOIN tblPrediction ON tblResult.GameID = tblPrediction.GameID) ON tblUser.UserID = tblPrediction.UserID
GROUP BY tblPrediction.GameID, tblPrediction.Joker, tblResult.GroupName, tblPool.PoolID
HAVING (((tblPrediction.Joker)=True) AND ((tblResult.GroupName)='A') AND ((tblPool.PoolID)=314));
Here is the output:
CountOfJoker GameID
2 1
2 2
2 9
1 10
1 17
3 18
I would like the MAX of CountOfJoker with the following output:
CountOfJoker GameID
3 18
Thanks
Drew
You could use select top and order by ... desc
SELECT TOP 1 Count(*) AS CountOfJoker, tblPrediction.GameID
FROM (tblUser INNER JOIN (tblPool INNER JOIN tblUserPool ON tblPool.PoolID = tblUserPool.PoolID) ON tblUser.UserID = tblUserPool.UserID) INNER JOIN (tblResult INNER JOIN tblPrediction ON tblResult.GameID = tblPrediction.GameID) ON tblUser.UserID = tblPrediction.UserID
GROUP BY tblPrediction.GameID, tblPrediction.Joker, tblResult.GroupName, tblPool.PoolID
HAVING (((tblPrediction.Joker)=True) AND ((tblResult.GroupName)='A') AND ((tblPool.PoolID)=314));
ORDER BY Count(*) DESC