SQL View how to Group By and Sum - sql

I have an Entries Table and a Members table and I want to sum all of the entries based on a member name. I've created a view to do this but I'm having a terrible time trying to get the syntax correct.
CREATE VIEW [dbo].[Members_View] AS
SELECT Members.ID, Members.Name, Members.Email,
(SELECT COUNT(*) WHERE AssignedTo = Members.Name) as ECount
From Members JOIN dbo.Entries ON Members.[Name] = Entries.[AssignedTo]
Group By
Name,
Members.ID,
Members.Email,
Entries.AssignedTo
If I remove the Group By I simply get the number 1 in my new ECount column for each entry but multiples of each name. Once I group by I only have one of each name but each entry still has only 1 count. How do I Group By AND Sum?

I think you can just do a simple aggregation query, leaving out Entries.AssignedTo:
CREATE VIEW [dbo].[Members_View] AS
SELECT Members.ID, Members.Name, Members.Email,
COUNT(*) as ECount
From Members JOIN
dbo.Entries
ON Members.[Name] = Entries.[AssignedTo]
Group By
Name,
Members.ID,
Members.Email;

You could count the entries in a sub-select and then join it to the main table
CREATE VIEW [dbo].[Members_View] AS
SELECT Members.ID, Members.Name, Members.Email, entries.ECount
FROM Members
JOIN (SELECT AssignedTo, COUNT(*) AS ECount FROM Entries GROUP BY AssignedTo) entries ON entries.AssignedTo = Members.Name

Related

Query all columns of table1 left join and count of the table2

I couldn't get this query working :
DOESN'T WORK
select
Region.*, count(secteur.*) count
from
Region
left join
secteur on secteur.region_id = Region.id
The solution I found is this but is there a better solution using joins or if this doesn't affect performance, because I have a very large dataset of about 500K rows
WORKS BUT AFRAID OF PERFORMANCE ISSUES
select
Region.*,
(select count(*)
from Secteur
where Secteur.Region_id = region.id) count
from
Region
I would suggest:
select region.*, count(secteur.region_id) as count
from region left join secteur on region.id = secteur.region_id
group by region.id, region.field2, region.field3....
Note that count(table.field) will ignore nulls, whereas count(*) will include them.
Alternatively, left join on a subquery and use coalesce to avoid nulls:
select region.*, coalesce(t.c, 0) as count
from region left join
(select region_id, count(*) as c from secteur group by region_id) t on region.id = t.region_id
I'd join region on an aggregate query of secteur:
SELECT r.*, COALESCE(s.cnt, 0)
FROM region r
LEFT JOIN (SELECT region_id, COUNT(*) AS cnt
FROM secteur
GROUP BY region_id) s ON s.region_id = r.id
I would go with this query:
select r.*,
(select count(*)
from Secteur s
where s.Region_id = r.id
) as num_secteurs
from Region r;
Then fix the performance problem by adding an index on Secteur(region_id):
create index idx_secteur_region on secteur(region_id);
You make a two mistakes
First: you have try to calulate COUNT() in only one (I mean, the second) table. This doesn't will work because theCOUNT(), like an any aggregate function, calculates only for the whole set of rows, not just for any part of the set (not only just for the one or an other joined table).
In your first query, you may replace secteur. * only by asterisk, like a Region.region_id, count(*) AS count, and do not forget add Region.region_id on the GROUP BY step.
Second: You has define not only aggregate function in the query, but and other fields: select Region.*, but you don't define them in GROUP BY step. You need to add to GROUP BY statement all columns, which you has define in the SELECT step but not apply an aggregate functions to them.
Append: not, GROUP BY Region.* doesn't will work, you should to define a columns in the GROUP BY step by their actual names.
So, correct form of this will looks like a
SELECT
Region.col1
,Region.col2,
, count(*) count
from Region
left join
secteur on secteur.region_id = Region.id
GROUP BY Region.col1, Region.col2
Or, if you don't want to type each name of column, use window queries
SELECT
Region.*,
, count( * ) OVER (PARTITION BY region_id) AS count
from Region
left join
secteur on secteur.region_id = Region.id

SQL Group By Throwing Up Error (SQL Server)

I have SQL code that throws up an error saying
Error: SQLCODE=-119, SQLSTATE=42803, SQLERRMC=WONUM
The code works fine until I add the group by:
select *
from workorder
left join labtrans on labtrans.refwo=workorder.wonum and labtrans.siteid=workorder.siteid
left join matusetrans on workorder.wonum=matusetrans.refwo and workorder.siteid=matusetrans.tositeid and linetype not in (select value from synonymdomain where domainid='LINETYPE' and maxvalue='TOOL')
left join locations on locations.location = workorder.location and locations.siteid=workorder.siteid
left join person on personid in (select personid from labor where laborcode = labtrans.laborcode)
left join po on workorder.wonum=po.hflwonum and workorder.siteid=po.siteid and workorder.orgid=po.orgid
left join companies on companies.company = po.vendor and companies.orgid=po.orgid
left join pluspcustomer on pluspcustomer.customer=workorder.pluspcustomer
where workorder.wonum='10192'
group by personid
;
if you only GROUP BY personid, you cannot select everything except personid, OR the fields used by aggregate functions such as SUM,MAX, etc
UPDATE
If you just want to see the duplicate personid, you could use:
select personid
from table
group by personid
But be careful here: If you write query like this, the only field that to determine the duplicate records is persionid, if you need to uniquely identify each persionid from different CompanyId, you need to group by persionid, CompanyId, otherwise, same personId from different company will be considered as the duplicate records.
But if you want to delete those duplicate records, you should use ROW_NUMBER()OVER (Partition by persionid Order by your_criteria) to delete the duplicate records. Try to do some searches to see how does that work, usually I prefer to use that function along with the CTE table expression.
if you just need to remove duplicates, use DISTINCT with your query like this:
your query:
SELECT * FROM .....
modify it:
SELECT DISTINCT * FROM .....
Hope it helps.

How to fetch all rows from table with count of specific group?

I have a simple table like this
spatialite> select id, group_id, object_id, object, param from controlled_object;
1|1|150|nodes|0.5
2|1|186|nodes|0.5
3|2|372|nodes|1.0
The second column is group_id. I want to retrieve all entries from the table, plus the count of the group.
1|1|150|nodes|0.5|2
2|1|186|nodes|0.5|2
3|2|372|nodes|1.0|1
I thought a cross join would be the way to go
SELECT
*
, cj.cnt
FROM
controlled_object
CROSS JOIN (
SELECT
COUNT(DISTINCT group_id) AS cnt
FROM
controlled_object
) AS cj
But that gives me
1|1|150|nodes|0.5|2|2
2|1|186|nodes|0.5|2|2
3|2|372|nodes|1.0|2|2
How do I fetch all rows from table including the count of a specific group?
Join source data with counters, grouped by group_id
select c.id, c.group_id, c.object_id, c.object, c.param,cnt from controlled_object c join
(select group_id,count(*) cnt from controlled_object group by group_id) p on c.group_id =p.group_id ;
Not very good idea for big tables
Sqlite is not very good idea for big tables at all :-)
You can compute the count with a correlated subquery:
SELECT id,
group_id,
object_id,
object,
param,
(SELECT count(*)
FROM controlled_object AS co2
WHERE group_id = controlled_object.group_id)
FROM controlled_object;

How do I count from 2 different tables in access sql

I have two tables, one that contains information about patients visits: PatientName,DoctorName,DataOfVisit, etc and the second table that contains information about doctors: DoctorName and DoctorSpeciality.
I need to create a query that will print me the PatientName, the number of doctors that patient went to, and the number of different specialties.
If I run
SELECT PatientName, COUNT(VISITS.DoctorName) as DocNum, Count(DoctorSpeciality) as SpecNum
FROM VISITS
INNER JOIN Doctors
ON VISITS.DoctorName = Doctors.DoctorName
GROUP BY PatientName, VISITS.DoctorName, DoctorSpeciality
I get the number of Doctors but not the number of Specialities and the patients are not grouped.
In most databases, you would just use count(distinct specialty). But, Access doesn't support that.
You can do what you want with two group bys:
SELECT PatientName, COUNT(*) as NumSpecialties, SUM(NumDocs) as NumDocs
FROM (SELECT PatientName, Doctors.DoctorSpeciality, COUNT(*) as NumDocs
FROM VISITS INNER JOIN
Doctors
ON VISITS.DoctorName = Doctors.DoctorName
GROUP BY PatientName, DoctorSpeciality
) as pd
GROUP BY PatientName;
You can add DISTINCT within your COUNT() function, also you should not include the aggregate fields in your GROUP BY.
Here is how I would change the query.
SELECT PatientName, COUNT(DISTINCT VISITS.DoctorName) as DocNum,
Count(DISTINCT DoctorSpeciality) as SpecNum
FROM VISITS INNER JOIN
Doctors ON VISITS.DoctorName = Doctors.DoctorName
GROUP BY PatientName
use table name with fields that you want to select from db
SELECT VISITS.PatientName, COUNT(VISITS.DoctorName) as DocNum, Count(Doctors.DoctorSpeciality) as SpecNum
FROM VISITS
INNER JOIN Doctors
ON VISITS.DoctorName = Doctors.DoctorName
GROUP BY PatientName, VISITS.DoctorName, DoctorSpeciality

how to use count with where clause in join query

SELECT
DEPTMST.DEPTID,
DEPTMST.DEPTNAME,
DEPTMST.CREATEDT,
COUNT(USRMST.UID)
FROM DEPTMASTER DEPTMST
INNER JOIN USERMASTER USRMST ON USRMST.DEPTID=DEPTMST.DEPTID
WHERE DEPTMST.CUSTID=1000 AND DEPTMST.STATUS='ACT
I have tried several combination but I keep getting error
Column 'DEPTMASTER.DeptID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause
I also add group by but it's not working
WHen using count like that you need to group on the selected columns,
ie.
SELECT
DEPTMST.DEPTID,
DEPTMST.DEPTNAME,
DEPTMST.CREATEDT,
COUNT(USRMST.UID)
FROM DEPTMASTER DEPTMST
INNER JOIN USERMASTER USRMST ON USRMST.DEPTID=DEPTMST.DEPTID
WHERE DEPTMST.CUSTID=1000 AND DEPTMST.STATUS='ACT'
GROUP BY DEPTMST.DEPTID,
DEPTMST.DEPTNAME,
DEPTMST.CREATEDT
you miss group by
SELECT DEPTMST.DEPTID,
DEPTMST.DEPTNAME,
DEPTMST.CREATEDT,
COUNT(USRMST.UID)
FROM DEPTMASTER DEPTMST
INNER JOIN USERMASTER USRMST ON USRMST.DEPTID=DEPTMST.DEPTID
WHERE DEPTMST.CUSTID=1000 AND DEPTMST.STATUS='ACT
group by DEPTMST.DEPTID,
DEPTMST.DEPTNAME,
DEPTMST.CREATEDT
All aggregate functions like averaging, counting,sum needs to be used along with a group by function. If you dont use a group by clause, you are performing the function on all the rows of the table.
Eg.
Select count(*) from table;
This returns the count of all the rows in the table.
Select count(*) from table group by name
This will first group the table data based on name and then return the count of each of these groups.
So in your case, if you want the countof USRMST.UID, group it by all the other columns in the select list.