Count string values From row using sql? - 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

Related

how to generate a report in sql server from a previous select

Periodically I need to generate a report based on some data from database.
The first select IS:
SELECT DISTINCT
A.PRO_C_NOME,
B.ETS_C_NOME
FROM WETI_ETAPA_ITEM F
INNER JOIN WETE_ETAPA_ITEM_EDITORS E
ON E.ETE_N_ETI_N_CODIGO = F.ETI_N_CODIGO
INNER JOIN WETA_ETAPA_PROCESSO H
ON H.ETA_N_CODIGO = F.ETI_N_ETA_N_CODIGO
INNER JOIN WIPR_ITEM_PROCESSO C
ON C.IPR_N_CODIGO = F.ETI_N_IPR_N_CODIGO
INNER JOIN WIWF_ITEM_WORKFLOW D
ON D.IWF_N_CODIGO = C.IPR_N_IWF_N_CODIGO
INNER JOIN WPRO_PROCESSO A
ON A.PRO_N_CODIGO = C.IPR_N_PRO_N_CODIGO AND PRO_N_DELETED = 0
LEFT OUTER JOIN WISP_ITEM_SUBPROCESS G
ON G.ISP_N_ID = F.ETI_ISP_N_ID
INNER JOIN WETS_ETAPA_SLA B
ON F.ETI_N_ETS_N_CODIGO = B.ETS_N_CODIGO
Returns something like this:
C1
C2
A
1
A
1
A
3
B
2
B
2
B
2
B
3
B
3
B
3
C
1
C
2
I need a report from that first select returning something like this:
S.1
S.2
S.3
S.4
A
2
0
1
B
0
3
3
C
1
1
0
that is:
S.1 - distinct values from C1
S.2 - count 1 values in C2 for the S.1 value
S.3 - count 2 values in C2 for the S.1 value
S.4 - count 3 values in C2 for the S.1 value
Can someone help how do I solve this?
I tried many solutions, such as using temporary tables and selecting from another select but doesn't work at all for different reasons.
;with cte(PRO_C_NOME, ETS_C_NOME) as (
SELECT DISTINCT
A.PRO_C_NOME,
B.ETS_C_NOME
FROM WETI_ETAPA_ITEM F
INNER JOIN WETE_ETAPA_ITEM_EDITORS E
ON E.ETE_N_ETI_N_CODIGO = F.ETI_N_CODIGO
INNER JOIN WETA_ETAPA_PROCESSO H
ON H.ETA_N_CODIGO = F.ETI_N_ETA_N_CODIGO
INNER JOIN WIPR_ITEM_PROCESSO C
ON C.IPR_N_CODIGO = F.ETI_N_IPR_N_CODIGO
INNER JOIN WIWF_ITEM_WORKFLOW D
ON D.IWF_N_CODIGO = C.IPR_N_IWF_N_CODIGO
INNER JOIN WPRO_PROCESSO A
ON A.PRO_N_CODIGO = C.IPR_N_PRO_N_CODIGO AND PRO_N_DELETED = 0
LEFT OUTER JOIN WISP_ITEM_SUBPROCESS G
ON G.ISP_N_ID = F.ETI_ISP_N_ID
INNER JOIN WETS_ETAPA_SLA B
ON F.ETI_N_ETS_N_CODIGO = B.ETS_N_CODIGO
)
SELECT PRO_C_NOME AS 'S.1'
,SUM(CASE WHEN ETS_C_NOME=1 THEN 1 ELSE 0 END) AS 'S.2'
,SUM(CASE WHEN ETS_C_NOME=2 THEN 1 ELSE 0 END) AS 'S.3'
,SUM(CASE WHEN ETS_C_NOME=3 THEN 1 ELSE 0 END) AS 'S.4'
FROM cte
GROUP BY PRO_C_NOME

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 Sum double counting

My SQL is double counting 'Fund1Amount' and 'Fund2Amount' and 'TotalAllDonations' I have a record where the values of the FundAmount1 should = 10 and FundAmount2 should = 20 but they equal 20 & 40 and the total is double. I am using INNER JOINs twice on the same table abc_donationdetail which i am not sure if this is the problem.
SELECT
C.FirstName, C.LastName,
SUM(D.abc_totalamount) AS TotalAllDonations,
SUM(CASE WHEN DBU.abc_fundidname = 'Fund1' THEN DBU.abc_amount END) AS Fund1Amount,
SUM(CASE WHEN DBE.abc_fundidname = 'Fund2' THEN DBE.abc_amount END) AS Fund2Amount
FROM
Contact C
INNER JOIN
Account A ON C.parentcustomerid = A.accountid
INNER JOIN
Account PA ON A.parentaccountid = PA.accountid
INNER JOIN
abc_donation D ON D.abc_person = C.contactid
LEFT JOIN
abc_donationdetail DBU ON DBU.abc_donationid = D.abc_donationid
AND DBU.abc_fundidname= 'Fund1'
LEFT JOIN
abc_donationdetail DBE ON DBE.abc_donationid = D.abc_donationid
AND DBE.abc_fundidname = 'Fund2'
LEFT JOIN
abc_mmcs GD ON GD.abc_donor = C.contactid
LEFT JOIN
sab_item LIBU ON LIBU.sab_itemid = GD.abc_companyid
AND LIBU.sab_name = 'Fund1'
LEFT JOIN
sab_item LIBE ON LIBE.sab_itemid = GD.abc_companyid
AND LIBE.sab_name = 'Fund2'
where C.StateCode = 0 AND (GD.abc_enddate > GETDATE() or GD.abc_enddate IS NULL)
group by C.abc_memberid, C.FirstName, C.LastName , C.StateCode, A.name, A.parentaccountidname, A.dd_number, PA.dd_number, C.parentcustomeridname
order by C.lastname
Current
FN LN Total Fund1 Fund2
James Brown 70 40 30
Phillip Smith 160 60 100
Peter Jones 80 40 40
Vincent Limp 48 48 NULL
Michael Collins 60 60 NULL
Desired
FN LN Total Fund1 Fund2
James Brown 35 20 15
Phillip Smith 80 30 50
Peter Jones 40 20 20
Vincent Limp 24 24 NULL
Michael Collins 30 30 NULL
Any help would be great.
Thanks
If the problem is only in duplicates, than simply make a subquery:
Select fld, sum(value)
from (select distinct fld, value from tbl) as a
I can't say much here as there are lots of tables joined here and I don't know their schema. At most, I can suggest you to add group by with person's id and fund id as it'll remove the duplicates.
SELECT
C.FirstName, C.LastName,
SUM(D.abc_totalamount) AS TotalAllDonations,
SUM(CASE WHEN DBU.abc_fundidname = 'Fund1' THEN DBU.abc_amount END) AS Fund1Amount,
SUM(CASE WHEN DBU.abc_fundidname = 'Fund2' THEN DBU.abc_amount END) AS Fund2Amount
FROM
Contact C
INNER JOIN
Account A ON C.parentcustomerid = A.accountid
INNER JOIN
Account PA ON A.parentaccountid = PA.accountid
INNER JOIN
abc_donation D ON D.abc_person = C.contactid
LEFT JOIN
abc_donationdetail DBU ON DBU.abc_donationid = D.abc_donationid
AND (DBU.abc_fundidname= 'Fund1'
OR DBU.abc_fundidname = 'Fund2') //MERGED 2 JOINS
LEFT JOIN
abc_mmcs GD ON GD.abc_donor = C.contactid
LEFT JOIN
sab_item LIBU ON LIBU.sab_itemid = GD.abc_companyid
AND LIBU.sab_name = 'Fund1'
LEFT JOIN
sab_item LIBE ON LIBE.sab_itemid = GD.abc_companyid
AND LIBE.sab_name = 'Fund2'
where C.StateCode = 0 AND (GD.abc_enddate > GETDATE() or GD.abc_enddate IS NULL)
group by C.abc_memberid, C.FirstName, C.LastName , C.StateCode, A.name, A.parentaccountidname, A.dd_number, PA.dd_number, C.parentcustomeridname order by C.lastname
Hope it works!

Inner join - more than one table

I'm trying to write a code that will join together information from 3 tables and compare it with a "big table" and according to the comparison update a field in a test table. Look at the example:
Big Table:
Employee_Id status
2322 5
222 3
545 6
4532 2
Table 1:
S_Id status
2322 7
Table 2:
S_Id status
222 3
Table 3:
S_Id status
545 6
4532 3
Test Table:
TE_Id IsNotGood
2322 1
4532 1
222 0
545 0
The id "2322" got 1 because the status in table 1 is not like the status in the big table and same for 4532.
I started writing this:
update Test Table
set isNotGood = 0
with ids as (
select distinct Employee_Id from (
select Employee_Id,Status from BigTable as B
) as T
inner join table1 as W on W.S_ID = T.Employee_Id
inner join table2 as K on K.S_ID = T.Employee_Id
inner join table3 as R on R.S_ID = T.Employee_Id
)
I would be happy for your tips to finish this query.
Thank you very much!
You won't be able to use an inner join unless the employee_id is in all the tables.
UPDATE Test
SET isNotGood = 1
WHERE te_id in (select employee_id
from [Big Table] bt
left join table1 as W on W.s_id = bt.employee_Id
left join table2 as K on K.s_id = bt.employee_Id
left join table3 as R on R.s_id = bt.employee_Id
where (bt.status <> W.status and W.status is not null) or (bt.status <> K.status and k.status is not null) or (bt.status <> R.status and R.status is not null);

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.)