I'm writing a query that counts company complaints. The query should count the total number of complaints from a company and also break it down into who called from the company to make the complaint. So an example output would be:
Company Ref Company Name Company Complaints Caller Caller Complaints
11 Argos 10 Steve 8
11 Argos 10 JIM 2
So as you can see the query counts the total number of complaints, then also breaks it down to who complained. So far I have everything perfect apart from the total count. My code is:
SELECT COMPANYREF,
COMPANY,
(SELECT COUNT(COMPANYREF)
FROM XCALLSTABLE) AS CompanyCalls,
CALLER,
COUNT(*)
FROM XCALLSTABLE
JOIN XCUSTOMERTABLE ON (XCALLSTABLE.COMPANYREF = XCUSTOMERTABLE.CUSTREF)
JOIN XTELEPHONETABLE ON (XCUSTOMERTABLE.TELEPHONE = XTELEPHONETABLE.PHONENUMBER)
GROUP BY COMPANYREF,
COMPANY,
CALLER
HAVING COUNT(*) > 0 ;
Some sample output for the current code is:
Company Ref Company Name Company Complaints Caller Caller Complaints
145 Comfiture Traders 500 Alexis Patel 4
The issue here is the total count for the company just counts every row, whereas I'm trying to count the occurances of that company appearing in the column.
Any and all help would be greatly appreciated.
Using sstan's code gave a result of
111 Medusa Shipping 4 Lily Morgan 5
111 Medusa Shipping 4 Ruby Walker 6
Whereas the result should be
111 Medusa Shipping 11 Lily Morgan 5
111 Medusa Shipping 11 Ruby Walker 6
I'm sure there is a cleaner way of doing this, but the following query should work:
SELECT companyref,
company,
CompanyCalls,
caller,
COUNT(*)
FROM (SELECT c.companyref,
company,
COUNT(*) OVER (PARTITION BY c.companyref) AS CompanyCalls,
caller
FROM xcallstable c
JOIN xcustomertable ct
ON ct.custref = c.companyref
JOIN xtelephonetable t
ON t.phonenumber = ct.telephone)
GROUP BY companyref, company, CompanyCalls, caller
HAVING COUNT(*) > 0
Related
I have the following data:
CompanyID
Department
No of People
Country
45390
HR
100
UK
45390
Service
250
UK
98712
Service
300
US
39284
Admin
142
Norway
85932
Admin
260
Germany
I wish to know how many people belong to the same department from different countries?
Required Output
Department
No of People
Country
HR
100
UK
Service
250
UK
300
US
Admin
142
Norway
260
Germany
I was able to get the data but the Department was repeated by this query.
""" select Department, Country,count(Department) from dataset
group by Country,Department
order by Department """
How can I get the desired output?
The result set that you are producing is not really a relational result set. Why? Because rows depend on what is in the "previous" row. And in a relational database, there is no such thing as a "previous" row. This type of processing is often handled in the application layer.
Of course, SQL can do what you want. You just need to be careful:
select (case when 1 = row_number() over (partition by Department order by Country)
then Department
end) as Department,
Country, count(*) as num_people,
from dataset
group by Country,Department
order by Department, Country;
Note that the order by needs to match the window function clause to be sure that what row_number() considered to be the first row is really the first row in the result set.
I want to get the subscriber that has maximum value of Bill (Total Bill).
I tried using the following script but SQL did not execute successflly.
Please help me on what I did wrong on this.
I have 2 tables:
Subscriber
FirstName
MIN
Ben
258999542
Reed
458524896
Steve
586692155
Clint
1007772121
Frank
1287548752
Jane
2345824215
Total Bill
Total
MIN
131.5
258999542
139.4
458524896
164
586692155
101
1007772121
224.12
1287548752
97.52
2345824215
And here's the code I tried:
SELECT MAX(B.Total), S.FirstName
FROM Subscriber AS S
JOIN Bill AS B ON S.MIN = B.MIN
It seems you just need TOP + ORDER BY:
SELECT TOP 1 B.Total, S.FirstName
FROM Subscriber AS S
JOIN Bill AS B ON S.MIN = B.MIN
ORDER BY B.Total DESC;
That's based on the fact that your sample data isn't showing multiple Bill records per Subscriber therefore you don't need a sum.
I'm trying to count the Total Number of Supervisors for each branch according to branch ID (B001, B002, B003). I'm trying to get the result like 'Sandy' counted as 1 and 'Mandy' counted as another (total 2 supervisors for B001) but after i executed, the result showed 3 (Sandy counted separately as 2 different values instead of 1). so, what should i do to make total number of supervisor in B001 branch becomes 2.
there are 3 B001 in that table, but the supervisors are only sandy and mandy which Supervisor Sandy is repeated. The result showed there are 3 supervisors after i executed, so how can i make it to 2?)
results shown:
2
SELECT Staff.BranchID,Branch.Manager AS ManagerName,
COUNT (staff.Supervisor) AS TotalNumberofSupervisor
FROM Staff INNER JOIN Branch ON Branch.BranchID = Staff.BranchID
GROUP BY Staff.BranchID,Branch.Manager
I think "COUNT (distinct(staff.Supervisor))" instead of
"COUNT (staff.Supervisor)" will help
I have 2 tables joined with political results and I need to have the votes SUM per county, and then the MAX of the vote counts per county, with the Party that relates to the MAX in another column. I'm having trouble getting the Party into the Query results without messing up the SUM and MAX columns.
This Table I can get with the Following SQL
County Name SumOfVoteCount MaxOfVoteCount OfficeID
Baker 7253 4008 S
SELECT NY_Race.[County Name], Sum(NY_Results.VoteCount) AS SumOfVoteCount, Max(NY_Results.VoteCount) AS MaxOfVoteCount
FROM NY_Race INNER JOIN NY_Results ON NY_Race.RaceCountyID = NY_Results.RaceCountyID
GROUP BY NY_Race.[County Name], NY_Race.OfficeID
HAVING (((NY_Race.OfficeID)="S"));
What I need is for the Party that has that 4008 vote total to be included in the query results, but when I try to select Party to be added, it shows all of them and messes up the SUM of the vote count, and I end of with this:
County Name SumOfVoteCount MaxOfVoteCount1 Party OfficeID
Baker 2927 2927 Dem S
Baker 4008 4008 GOP S
Baker 101 101 Lib S
Baker 53 53 Prg S
Baker 164 164 WF S
This is the SQL code I am using that gets the above Table:
SELECT NY_Race.[County Name], Sum(NY_Results.VoteCount) AS SumOfVoteCount, Max(NY_Results.VoteCount) AS MaxOfVoteCount, NY_Results.Party
FROM NY_Race INNER JOIN NY_Results ON NY_Race.RaceCountyID = NY_Results.RaceCountyID
GROUP BY NY_Race.[County Name], NY_Race.OfficeID, NY_Results.Party
HAVING (((OR_Race.OfficeID)="S"));
How can I get this table in the query results?
County Name SumOfVoteCount MaxOfVoteCount Party OfficeID
Baker 7253 4008 GOP S
I can't help but think I'm missing a WHERE claus somewhere that compares Party to MAXofVoteCount
One way to approach these is to have a nested subquery that gets the MAX() for the field of interest. Then, only select the record with that MAX(). Here's the structure:
select COUNTY_NAME, R1.*
, (select sum(votecount) from results R2 where R1.COUNTY_ID=R2.COUNTY_ID and R1.OFFICE_ID=R2.OFFICE_ID)
from RESULTS R1
join RACE on R1.COUNTY_ID=RACE.COUNTY_ID and R1.OFFICE_ID=RACE.OFFICE_ID
where R1.office_id = 'S'
and voteCount =
(select max(votecount) from results R3 where R1.COUNTY_ID=R3.COUNTY_ID and R1.OFFICE_ID=R3.OFFICE_ID)
I created a demo on SQLFiddle.
One issue: what if two get exactly the same number of votes. That's a functional issue you will have to resolve.
This is my SQL View - lets call it MyView :
ECode SHCode TotalNrShare CountryCode Country
000001 +00010 100 UKI United Kingdom
000001 ABENSO 900 USA United States
000355 +00012 1000 ESP Spain
000355 000010 50 FRA France
000042 009999 10 GER Germany
000042 +00012 999 ESP Spain
000787 ABENSO 500 USA United States
000787 000150 500 ITA Italy
001010 009999 100 GER Germany
I would like to return the single row with the highest number in the column TotalNrShare for each ECode.
For example, I’d like to return these results from the above view:
ECode SHCode TotalNrShare CountryCode Country
000001 ABENSO 900 USA United States
000355 +00012 1000 ESP Spain
000042 +00012 999 ESP Spain
000787 ABENSO 500 USA United States
001010 009999 100 GER Germany
(note in the case of ECode 000787 where there are two SHCode's with 500 each, as they are the same amount we can just return the first row rather than both, it isnt important for me which row is returned since this will happen very rarely and my analysis doesnt need to be 100%)
Ive tried various things but do not seem to be able to return either unqiue results or the additional country code/country info that I need.
This is one of my attempts (based on other solutions on this site, but I am doing something wrong):
SELECT tsh.ECode, tsh.SHCode, tsh.TotalNrShare, tsh.CountryCode, tsh.Country
FROM dbo.MyView AS tsh INNER JOIN
(SELECT DISTINCT ECode, MAX(TotalNrShare) AS MaxTotalSH
FROM dbo.MyView
GROUP BY ECode) AS groupedtsh ON tsh.ECode = groupedtsh.ECode AND tsh.TotalNrShare = groupedtsh.MaxTotalSH
WITH
sequenced_data AS
(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY ECode ORDER BY TotalNrShare) AS sequence_id
FROM
myView
)
SELECT
*
FROM
sequenced_data
WHERE
sequence_id = 1
This should, however, give the same results as your example query. It's simply a different approach to accomplish the same thing.
As you say that something is wrong, however, please could you elaborate on what is going wrong? Is TotalNrShare actually a string for example? And is that messing up your ordering (and so the MAX())?
EDIT:
Even if the above code was not compatible with your SQL Server, it shouldn't crash it out completely. You should just get an error message. Try executing Select * By Magic, for example, and it should just give an error. I strongly suggest getting your installation of Management Studio looked at and/or re-installed.
In terms of an alternative, you could do this...
SELECT
*
FROM
(SELECT ECode FROM MyView GROUP BY ECode) AS base
CROSS APPLY
(SELECT TOP 1 * FROM MyView WHERE ECode = base.ECode ORDER BY TotalNrShare DESC) AS data
Ideally you would replace the base sub-query with a table that already has a distinct list of all the ECodes that you are interested in.
try this;
with cte as(
SELECT tsh.ECode, tsh.SHCode, tsh.TotalNrShare, tsh.CountryCode, tsh.Country,
ROW_NUMBER() over (partition by ECode order by SHCode ) as row_num
FROM dbo.MyView)
select * from cte where row_num=1