Adding a new column in this SQL Query? - sql

I am querying data from the WIP and Employee tables:
WIP
Id,Name
Employee
Id,Name,Orgnization
Joining both I can query:
select w.ID,e.Organization,w.ConsultantName,e.OrganizationID, w.ConsultantID
from vwWIPRecords w
inner join vwEmployees e on w.ConsultantID=e.ID;
Resutls:
1 VHAA Web User 1 1
2 VHAA NZ RP 1 3
3 VHAA Ghom Mure 1 2
4 VHAA Ghom Mure 1 2
Requirment:
In query add anther column which will concatenate and group by e.Organization and e.ConsultantName but it will be only for first unique record. For next (where name and organization is same) it will not show anything. This column will show unique Consultants of a company. Please see record number 3 and 4 in second example.
1 VHAAWeb User 1 1
2 VHAANZ RP 1 3
3 VHAAGhom Mure 1 2
4 1 2
Thanks a lot for your help

Here is a start. The final column is a flag indicating the row should be blank. Let me know if this works for you so far and I can help further.
select w.ID,e.Organization, w.ConsultantName,
e.OrganizationID, w.ConsultantID, CASE WHEN D.Dup > 1 AND D.ID <> w.ID THEN 'Y'
ELSE 'N' END As HideMe
from vwWIPRecords w
inner join vwEmployees e on w.ConsultantID=e.ID
inner join
(
select MIN(w.ID) As ID, e.Organization,w.ConsultantName,
e.OrganizationID, w.ConsultantID, COUNT(*) AS Dup
from vwWIPRecords w
inner join vwEmployees e on w.ConsultantID=e.ID
) D
ON D.Organization = w.Organization
AND D.ConsultantName = w.ConsultantName
AND D.OrganizationID = w.OrganizationID
AND D.ConsultantID = w.ConsultantID

Related

I have a SUM function in my SELECT but don't want it to show

I want to see the companies which deliver the most sold items in my DB.
Currently i have this Code:
SELECT L."Firma", SUM("B"."Anzahl")
FROM "Bestelldetails" B, "Artikel" A, "Lieferanten" L
WHERE L."Lieferanten-Nr" = A."Lieferanten-Nr"
AND A."Artikel-Nr" = B."Artikel-Nr"
GROUP BY L."Firma"
ORDER BY 2 DESC
The Output that i get:
Firma
2
Company 1
2756
Company 2
2377
Company 3
2063
...many more...
..XXX..
The Output that i want:
Firma
Company 1
Company 2
Company 3
...many more...
Code with output as image
But i don't want the row with the number 2 to show. I just want the Company-Names to show. How would i do so?
Simply ORDER BY the SUM():
SELECT L."Firma"
FROM "Bestelldetails" B
JOIN "Artikel" A
ON A."Artikel-Nr" = B."Artikel-Nr"
JOIN "Lieferanten" L
ON L."Lieferanten-Nr" = A."Lieferanten-Nr"
GROUP BY L."Firma"
ORDER BY SUM("B"."Anzahl") DESC
(Now using proper, explicit JOIN syntax.)
select Firma from
(
SELECT L."Firma", SUM("B"."Anzahl")
FROM "Bestelldetails" B, "Artikel" A, "Lieferanten" L
WHERE L."Lieferanten-Nr" = A."Lieferanten-Nr"
AND A."Artikel-Nr" = B."Artikel-Nr"
GROUP BY L."Firma"
ORDER BY 2 DESC
);

SQL subquery for function count

The first column is the name of the locality,the second column is the number of voters in every locality..
my problem is on the third column because im trying to count voters that are unemployment but is counting all voters.sorry for my english.
select l.nombre as "Nombre",count(v.dni) as "Votantes",
(select count(v.dni) from localidades l,votantes v
where v.localidad=l.idlocalidad and v.situacionlaboral='Parado') as "Parados"
from votantes v,localidades l
where v.localidad=l.idlocalidad
group by l.nombre;
this is the out:
"Nombre" "Votantes" "Parados"
Sevilla 3 4
Baena 1 4
Córdoba 3 4
Montilla 1 4
Madrid 3 4
Utrera 3 4
Carmona 1 4
Badalona 1 4
Getafe 1 4
Try this:
select l.nombre as "Nombre"
, count(v.dni) as "Votantes"
, sum(case when situacionlaboral = 'Parado' then 1
else 0
end) as "Parados"
from votantes v
join localidades l on v.localidad=l.idlocalidad
group by l.nombre;
When you join two tables please do it like this:
from localidades l
join votantes v on v.localidad = l.idlocalidad
And not like this:
from localidades l,votantes v
where v.localidad=l.idlocalidad
If you want the total votes, use window functions:
select l.nombre, count(*) as Votantes,
sum(count(*)) over () as parados
from votantes v join
localidades l
on v.localidad = l.idlocalidad
group by l.nombre;
Also learn to use proper, explicit, standard JOIN syntax.

To join four table in mssql

MaingroupTable
MubGroupCodeid MainName maincode
1 Health 098
2 Social 078
SubGroup Table
SubGroupCodeid SubName subcode
1 Nursing 211
2 Civics 224
SubandMainGroup table
subandmainid **MubGroupCodeid** **subgroupcodeid**
1 1 1
2 2 2
Student Table
studid studname **subandmainid** (foriegn key of **subandmain group** table)
1 Alex 1
2 siraj 2
then I want to join and concatinate studname-maingroupcode-subgroupcode to get output like below
Alex-098-211
siraj-078-224
This will get you started and explain the joins. You'll probably also want to do some casting for the maincode and subcode, but since it's not 100% clear they aren't already varchar values I left that out.
SELECT s.studname + '-' + m.maincode + '-' + s.subcode
FROM Student s
INNER JOIN SubandMainGroup smg on smg.subandmainid = s.subandmainid
INNER JOIN MainGroup m on m.mubgroupcodeid = smg.mubgroupcodeid
INNER JOIN SubGroup s on s.subgroupcodeid = smg.subgroupcodeid
use join and concat all the required column by using ||
select s.studname ||'-'||subG.subcode ||'-' M.maincode
from
Student s join SubandMainGroup subM on s.subandmainid=subM.subandmainid
join SubGroup subG on subG.SubGroupCodeid=subM.subgroupcodeid
join MaingroupTable M on M.MubGroupCodeid=subM.MubGroupCodeid
Use the below query to solve the problem.
select stu.studname + '-'+mgrp.maincode +'-'+sgrp.subcode from Student_ stu
join Maingroup mgrp on stu.studid=mgrp.MubGroupCodeid
join SubGroup sgrp on sgrp.SubGroupCodeid=stu.studid

Combining SQL Tables for one source of information

I'm trying to combine 3 different tables into one single row in a query but having some problems. Currently I have four tables; PaintSched, Painted_Log, Paint_Defect, and Paint_Inspection.
PaintSched - Single entry, when scheduler just schedules some parts to be painted
LOT QTY
1 150
2 100
Painted_Log - The paint department then takes the lot and says how many they were able to paint
LOT(FK) QTYPainted
1 145
2 100
Paint_Defect - Master List of defects for paint inspection after parts have been painted. We hand inspect all of our parts that we paint for quality.
DID Defect
1 Scratch
2 Paint Run
Paint_Inspection - Everytime a defect is found the inspector hits a correlating button and the following gets logged. Lot is FK and DID stands for Defect ID from Paint_Defect. QTY is always 1
Lot(FK) DID(FK) QTY
1 1 1
1 1 1
1 2 1
1 1 1
2 2 1
1 2 1
2 1 1
What I'm trying to get is the following output:
Lot Sched Painted Scratch Paint Run
1 150 145 3 2
2 100 100 1 1
I've tried the following to no avail:
SELECT PaintSched.Scheduled, PaintSched.Lot, PaintSched.qty, PaintSched.Is_Painted, Painted_Log.falloff
FROM PaintSched
INNER JOIN Painted_Log ON PaintSched.Lot = Painted_Log.lot
INNER JOIN MPA_Desc ON MPA_Desc.MPAID = PaintSched.MPAID
inner JOIN (
SELECT lot, sum(Paint_Inspection.qty) as seds
FROM Paint_Inspection
WHERE Paint_Inspection.Status = '1'
) AS seeds ON PaintSched.Lot = Paint_Inspection.Lot
SELECT
PS.Lot,
PS.Qty Sched,
Painted,
Scratch,
PaintRun
FROM PaintSched PS
LEFT JOIN (SELECT
Lot,
SUM(QTYPainted) Painted
FROM Painted_Log GROUP BY Lot) PL
ON PS.Lot = PL.Lot
LEFT JOIN (SELECT
Lot,
SUM(CASE WHEN DID = 1 THEN 1 ELSE 0 END) Scratch,
SUM(CASE WHEN DID = 2 THEN 1 ELSE 0 END) PaintRun
FROM Paint_Inspection GROUP BY Lot) PI
ON PS.Lot = PI.Lot
Try that in SQL Fiddle
The code above uses conditional sum to roll up the defect count by type before joining that to the lot id. If you have more than 2 statuses, you will need to update the above code accordingly.
Two things:
You should have a group by in the subquery
When you alias the subquery, you don't join it properly
See the edits to your query below:
SELECT
PaintSched.Scheduled,
PaintSched.Lot,
PaintSched.qty,
PaintSched.Is_Painted,
Painted_Log.falloff
FROM PaintSched
INNER JOIN Painted_Log ON PaintSched.Lot = Painted_Log.lot
INNER JOIN MPA_Desc ON MPA_Desc.MPAID = PaintSched.MPAID
INNER JOIN (
SELECT lot, sum(Paint_Inspection.qty) as seds
FROM Paint_Inspection
WHERE Paint_Inspection.Status = '1'
GROUP BY Paint_Inspection.lot -- Missing GROUP BY
) AS seeds
ON PaintSched.Lot = seeds.Lot

how to write this query using joins?

i have a table campaign which has details of campaign mails sent.
campaign_table: campaign_id campaign_name flag
1 test1 1
2 test2 1
3 test3 0
another table campaign activity which has details of campaign activities.
campaign_activity: campaign_id is_clicked is_opened
1 0 1
1 1 0
2 0 1
2 1 0
I want to get all campaigns with flag value 3 and the number of is_clicked columns with value 1 and number of columns with is_opened value 1 in a single query.
ie. campaign_id campaign_name numberofclicks numberofopens
1 test1 1 1
2 test2 1 1
I did this using sub-query with the query:
select c.campaign_id,c.campaign_name,
(SELECT count(campaign_id) from campaign_activity WHERE campaign_id=c.id AND is_clicked=1) as numberofclicks,
(SELECT count(campaign_id) from campaign_activity WHERE campaign_id=c.id AND is_clicked=1) as numberofopens
FROM
campaign c
WHERE c.flag=1
But people say that using sub-queries are not a good coding convention and you have to use join instead of sub-queries. But i don't know how to get the same result using join. I consulted with some of my colleagues and they are saying that its not possible to use join in this situation. Is it possible to get the same result using joins? if yes, please tell me how.
This should do the trick. Substitute INNER JOIN for LEFT OUTER JOIN if you want to include campaigns which have no activity.
SELECT
c.Campaign_ID
, c.Campaign_Name
, SUM(CASE WHEN a.Is_Clicked = 1 THEN 1 ELSE 0 END) AS NumberOfClicks
, SUM(CASE WHEN a.Is_Opened = 1 THEN 1 ELSE 0 END) AS NumberOfOpens
FROM
dbo.Campaign c
INNER JOIN
dbo.Campaign_Activity a
ON a.Campaign_ID = c.Campaign_ID
GROUP BY
c.Campaign_ID
, c.Campaign_Name
Assuming is_clicked and is_opened are only ever 1 or 0, this should work:
select c.campaign_id, c.campaign_name, sum(d.is_clicked), sum(d.is_opened)
from campaign c inner join campaign_activity d
on c.campaign_id = d.campaign_id
where c.flag = 1
group by c.campaign_id, c.campaign_name
No sub-queries.
Hmm. Is what you want as simple as this? I'm not sure I'm reading the question right...
SELECT
campaign_table.campaign_id, SUM(is_clicked), SUM(is_opened)
FROM
campaign_table
INNER JOIN campaign_activity ON campaign_table.campaign_id = campaign_activity.campaign_id
WHERE
campaign_table.flag = 1
GROUP BY
campaign_table.campaign_id
Note that with an INNER JOIN here, you won't see campaigns where there's nothing corresponding in the campaign_activity table. In that circumstance, you should use a LEFT JOIN, and convert NULL to 0 in the SUM, e.g. SUM(IFNULL(is_clicked, 0)).
I suppose this should do it :
select * from campaign_table inner join campaign_activity on campaign_table.id = campaign_activity.id where campaign_table.flag = 3 and campaign_activity.is_clicked = 1 and campaign_activity.is_opened = 1
Attn : this is not tested in a live situation
The SQL in it's simplest form and most robust form is this: (formatted for readability)
SELECT
campaign_table.campaign_ID, campaign_table.campaign_name, Sum(campaign_activity.is_clicked) AS numberofclicks, Sum(campaign_activity.is_open) AS numberofopens
FROM
campaign_table INNER JOIN campaign_activity ON campaign_table.campaign_ID = campaign_activity.campaign_ID
GROUP BY
campaign_table.campaign_ID, campaign_table.campaign_name, campaign_table.flag
HAVING
campaign_table.flag=1;