SQL subquery for function count - sql

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.

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

Adding a new column in this SQL Query?

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

SQLite - check if any field has a 1 on each column

I have the following query:
SELECT c.danhoEstetico, c.danhoDirecto
FROM conceptos c
INNER JOIN materialesconceptos mc ON mc.idConcepto = c.idConcepto
INNER JOIN materiales m ON m.idMaterial = mc.idMaterial
WHERE m.idMaterial IN (4,11,11)
Which yields the following result (for example):
danhoEstetico | danhoDirecto
1 | 0
1 | 0
0 | 0
0 | 0
I need to make a query that gives me if any of the items in each column has a 1, like an OR among all the fields in the same column, with an output like:
danhoEstetico | danhoDirecto
1 | 0
I have tried:
SELECT
SUM(CASE c.danhoEstetico WHEN c.danhoEstetico=1 THEN 1 ELSE 0 END) AS de,
SUM(CASE c.danhoDirecto WHEN c.danhoDirecto=1 THEN 1 ELSE 0 END) AS dd
FROM conceptos c INNER JOIN materialesconceptos mc ON mc.idConcepto = c.idConcepto
INNER JOIN materiales m ON m.idMaterial = mc.idMaterial
WHERE m.idMaterial IN (4,11,11)
Which, for some reason, yields:
danhoEstetico | danhoDirecto
4 | 4
Any hint on this?
To get the largest value in each column, use MAX instead of SUM.
Edit: I misread the question. This solution checks that every row in a column is 1, rather than any row. I recommend CL's answer, but I will leave this answer here because it explains a problem with the CASE statement in the question.
You should be using CASE without a base expression:
SELECT
SUM(CASE WHEN c.danhoEstetico=1 THEN 1 ELSE 0 END) AS de,
SUM(CASE WHEN c.danhoDirecto=1 THEN 1 ELSE 0 END) AS dd
FROM conceptos c INNER JOIN materialesconceptos mc ON
mc.idConcepto = c.idConcepto
INNER JOIN materiales m ON m.idMaterial = mc.idMaterial
WHERE m.idMaterial IN (4,11,11)
From the documentation:
In a CASE with a base expression, the base expression is evaluated
just once and the result is compared against the evaluation of each
WHEN expression from left to right. The result of the CASE expression
is the evaluation of the THEN expression that corresponds to the first
WHEN expression for which the comparison is true...
In your statement as written, the case statement always evaluated to 1 when the column was 1 and 0 when the column was 0. Thus, they always matched, and the sum was always the number of rows.
Update: now how do you actually turn this into the result you want? Here is one way:
SELECT
SUM(CASE WHEN c.danhoEstetico=1 THEN 1 ELSE 0 END) / SUM(1) AS de,
SUM(CASE WHEN c.danhoDirecto=1 THEN 1 ELSE 0 END) / SUM(1) AS dd
FROM conceptos c INNER JOIN materialesconceptos mc ON
mc.idConcepto = c.idConcepto
INNER JOIN materiales m ON m.idMaterial = mc.idMaterial
WHERE m.idMaterial IN (4,11,11)
This takes advantage of integer arithmetic. The division will result in a value < 1 if not all rows in a column are one, and a value less than one will show as zero.
select distinct
c.danhoEstetico, c.danhoDirecto
FROM conceptos c
INNER JOIN materialesconceptos mc ON mc.idConcepto = c.idConcepto
INNER JOIN materiales m ON m.idMaterial = mc.idMaterial
where 1 in (c.danhoEstetico , c.danhoDirecto)

Join SQL Query Problem?

First Select Statement:
SELECT
dbo.FG_FILLIN.PartNumber,
dbo.DropshipPackinglist.Shiplist_Qty,
dbo.DropshipPackinglist.Quantity
FROM dbo.FG_FILLIN INNER JOIN
dbo.DropshipPackinglist ON
dbo.FG_FILLIN.PartNumber = dbo.DropshipPackinglist.PartNumber
WHERE (dbo.FG_FILLIN.Batch = 'CIP_HK_6')
GROUP BY
dbo.FG_FILLIN.Batch,
dbo.FG_FILLIN.PartNumber,
dbo.FG_FILLIN.ItemNumber,
dbo.DropshipPackinglist.Shiplist_Qty,
dbo.DropshipPackinglist.Quantity
Result :
PartNumber Shiplist_Qty Quantity
P02-070161-00111-C100 6 3
P02-070161-10111-C100 6 3
2nd :
SELECT PartNumber,COUNT(Batch) AS Created
FROM dbo.FG_FILLIN
WHERE Batch='CIP_HK_6'
GROUP BY Batch,PartNumber
Result :
PartNumber Created
P02-070161-00111-C100 3
P02-070161-10111-C100 1
Joining this two Query I cant show this one: RESULT NEEDED
PartNumber Shiplist_Qty Quantity Created
P02-070161-00111-C100 6 3 3
P02-070161-10111-C100 6 3 1
It always show : when i Add Count(dbo.FG_FILLIN.Batch) as Created
PartNumber Shiplist_Qty Quantity Created
P02-070161-00111-C100 6 3 6
P02-070161-10111-C100 6 3 2
Any Advice.? Thanks In Regards!
Using a subselect:
SELECT f.PartNumber,
dpl.Shiplist_Qty,
dpl.Quantity,
(SELECT COUNT(Batch) AS Created
FROM dbo.FG_FILLIN x
WHERE x.batch = f.batch
AND x.partnumber = f.partnumber
GROUP BY Batch, PartNumber) AS created
FROM dbo.FG_FILLIN f
JOIN dbo.DropshipPackinglist dpl ON dpl.partnumber = f.partnumber
WHERE f.Batch = 'CIP_HK_6'
GROUP BY f.Batch, f.PartNumber, f.ItemNumber, dpl.Shiplist_Qty, dpl.Quantity
Using a JOIN to a derived table/inline view
SELECT f.PartNumber,
dpl.Shiplist_Qty,
dpl.Quantity,
x.created
FROM dbo.FG_FILLIN f
JOIN dbo.DropshipPackinglist dpl ON dpl.partnumber = f.partnumber
LEFT JOIN (SELECT t.partnumber,
t.batch,
COUNT(Batch) AS Created
FROM dbo.FG_FILLIN t
GROUP BY Batch, PartNumber) x ON x.partnumber = f.partnumber
AND x.batch = f.batch
WHERE f.Batch = 'CIP_HK_6'
GROUP BY f.Batch, f.PartNumber, f.ItemNumber, dpl.Shiplist_Qty, dpl.Quantity
Change "LEFT JOIN" to "JOIN" if you only want to see parts that have created values.

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;