extend SQL result - add row if not exist - sql

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

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.

SQL split one column into two columns based on values and use columns

Table: ProductionOrder
Id Ordernumber Lotsize
1 Order1 50
2 Order 2 75
3 WO-order1 1
4 WO-order2 1
Table: history
Id ProductionOrderID Completed
1 3 1
2 3 1
3 4 1
4 4 1
Table: ProductionOrderDetail
ID ProductionOrderID ProductionOrderDetailDefID Content
1 1 16 50
2 1 17 7-1-2018
3 2 16 75
4 2 17 7-6-2018
Start of my code:
Select p.ID, p.OrderNumber,
Case productionOrderDetailDefID
Where(Select pd1.productionOrderDetailDefID where ProductionOrderDetialDefID = 16) then min(pd1.content)
from ProductionOrder p
Left join History h1 on p.id = h1.productionOrderID
Left Join ProductionOrderDetail pd1 on p.ID = ProductionOrderID
The result in trying to get is
Id Ordernumber Lotsize Productionorder Completed
1 Order1 50 WO-order1 2
2 Order 2 75 WO-order2 2
Any help would be appreciated.
Try this
SELECT ordernumber,lotsize,Ordernumber,count(Ordernumberid)
FROM productionorder inner join history on productionorder.id = history.Ordernumberid
GROUP BY Ordernumber;
A bit of weird joins going on here. You should add this to a SQL fiddle so that we can see our work easier.
A link to SQL fiddle: http://sqlfiddle.com/
Here is my first attempt
SELECT
po.id
, po.ordernumber
, po.lotsize
, po2.productionorder
, SUM(h.completed)
FROM productionorder as po
INNER JOIN history as h
ON h.id = po.id
INNER JOIN prodcuctionorder as po2
ON po2.ordernumberid = h.ordernumberid
WHERE po.id NOT EXISTS IN ( SELECT ordernumberid FROM history )
GROUP BY
po.id
, po.ordernumber
, po.lotzise
, po2.productionorder
How far does that get you?

Calculating weighted Average From DB

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.

Show null and not num values

My query
with with_user_earns as (
-- get father information (start)
select father.id, father.str_name, father.id_father, father.ind_father_side_type, 1 as int_user_level from tb_user father where id = #v_user_id
union all
-- get son information (stop condition)
select son.id, son.str_name, son.id_father, son.ind_father_side_type, WUE.int_user_level + 1
from tb_user as son inner join with_user_earns as WUE on son.id_father = WUE.id
where son.id_father is not null and WUE.int_user_level < #v_max_level
)
select aux.*
from (
-- show result
select with_user_earns.id id_son, with_user_earns.str_name str_son_name, with_user_earns.id_father, father.str_name str_father_name, with_user_earns.ind_father_side_type, with_user_earns.int_user_level, isnull(sum(o.int_score), 0) as int_score
from with_user_earns inner join tb_order o on o.id_user = with_user_earns.id
inner join tb_user as father on father.id = with_user_earns.id_father
where o.dt_insert between #v_cycle_begin and #v_cycle_end and o.ind_payment_status = 3
group by with_user_earns.id, with_user_earns.str_name, with_user_earns.id_father, with_user_earns.ind_father_side_type, with_user_earns.int_user_level, father.str_name
) as aux
order by aux.int_user_level, aux.id_son
The table with_user_earns contains a lot of users (mult nivel hierarchy).
Then I want to join with tb_order to get int_score 0 if the user sell nothing and if the user sell anything I want the sum of it.
I tried put left join, full outer join, ... But no one works perfect
What a need to do?
My result:
id_son int_score
1 100
2 11100
3 100
10 300
Expected result:
id_son int_score
1 100
2 11100
3 100
4 0
5 0
6 0
7 0
8 0
9 0
10 300

Inner join on two tables, with clause

with one as
(Select sno = ROW_NUMBER()OVER (order by complaint_id), Complaint_Id, Complaint.ComplaintType_id, Complaint.complaintProfileId, Complaint.Description,
Complaint.Email, Complaint.PriorityLevel_id, Complaint.Date_Complained, Complaint.Status, Complaint.AdminComments, Complaint.Phone, Complaint.Evidence
from Complaints Complaint )
The result of this query is (not the entire result)
sno complaintProfileId
1 14
2 15
3 15
4 14
5 14
6 13
The second subquery:
two as
(SELECT Complaint.complaintProfileId,
CASE
WHEN MMB_Name IS NOT NULL THEN MMB_Name
WHEN UPPMembership.profile_id IS NOT NULL THEN 'UPP'
ELSE 'Not found'
END as Name
FROM Complaints Complaint
LEFT JOIN MMBMembership
ON MMBMembership.profile_id = Complaint.complaintProfileId
left JOIN MMB_BusinessProfiles mmbProfiles
ON mmbProfiles.MMB_id = MMBMembership.MMB_id
LEFT JOIN UPPMembership
ON UPPMembership.profile_id = Complaint.complaintProfileId)
complaintProfileId Name
14 UPP
15 Marlon
15 Marlon
14 UPP
14 UPP
13 Rodolfo
So this is where I am having trouble with
select one.*, two.Name
from one join two
on one.complaintProfileId = two.complaintProfileId
This query returns 36 records. id 14 is being returned 9times and 15-6times and so on..
I am doing a inner join but still not sure
Thanks
Sun
You need to join on a unique key. Each '14' on the left side is being joined to each of the three '14's on the right side. (3x3=9)