Getting highest count using SQL Server - sql-server

I'm currently developing a voting system. I wrote a query to get all votes but it only display all the vote getter, not the highest vote. What should I add in my query to execute what I need. Here's the code.
SELECT DISTINCT
b.idnumber, b.candidate_name, semester,
(SELECT COUNT(rslt_ccandidateid) FROM rslt_mstr
WHERE rslt_ccandidateid = idnumber) AS 'numberOfVotes',
b.position, b.program, b.position_categ, b.party_name,
b.school, b.yearLevel, a.hierarchy
FROM
cddt_mstr b
INNER JOIN
Position_mstr a ON a.scposition_name = b.position
WHERE
b.POSITION_CATEG = 'SUPREME COUNCIL CANDIDATES'
AND semester = '2ND SEMESTER A.Y. 2012-2013'
ORDER BY
a.hierarchy, 'numberOfVotes' DESC

Something like the below might work. I am assuming that rslt_ccandidateid IS NOT the vote value there is some other column, which I am calling [vote_column_name], that contains the vote value. I am also assuming that the vote value is an integer column. Lastly I am assuming you don't want the sum of all votes just the highest of all votes.
SELECT DISTINCT b.idnumber, b.candidate_name, semester, (
SELECT MAX([vote_column_name])
FROM rslt_mstr
WHERE rslt_ccandidateid = idnumber
GROUP BY rslt_ccandidateid
) AS 'numberOfVotes', b.position, b.program, b.position_categ, b.party_name, b.school, b.yearLevel, a.hierarchy
FROM cddt_mstr b
INNER JOIN Position_mstr a ON a.scposition_name = b.position
WHERE b.POSITION_CATEG = 'SUPREME COUNCIL CANDIDATES'
AND semester = '2ND SEMESTER A.Y. 2012-2013'
ORDER BY a.hierarchy, 'numberOfVotes' DESC

Related

TSQL: Relational Division with Remainder (RDWR)

I have mapping table CandidatesSkills which holds the mapping between candidate and the skills they possess. Then I have another table JobRequirements that maps jobs and required skills for that jobs.
A candidate can apply to a job if he possesses ALL the required skills for that job. A candidate can have extra skills. Given CandiateID I want to find all the jobs that candidate can apply.
I think this is Relational Division with Remainder in SQL. And there is an article here that explains the exact issue. (Note: the article tries to find all Candidates who has ALL skills for the given job. My problem is exactly opposite. I am trying to find all Jobs that matches with given Candidate's skill)
Candidate's Skills
Job to required skills mapping
based on the dataset, the query below should return JobID 2,3 and 5
Here my SQL (based on Peter Larsson (PESO) Solution for RDNR/RDWR)
DECLARE #CandidateID INT = 1
SELECT JobID
FROM
(
SELECT jr.JobID
,cnt=SUM(CASE WHEN jr.SkillID = c.SkillID THEN 1 ELSE 0 END)
,Items=COUNT(*)
FROM dbo.JobRequirements AS jr
CROSS JOIN dbo.CandidatesSkills AS c
WHERE c.CandidateID = #CandidateID
GROUP BY jr.JobID, jr.SkillID
) d
GROUP BY JobID
HAVING SUM(cnt) = MIN(Items)
AND MIN(cnt) >= 0;
However, query does not return anything. Trying to find what's wrong with my query
Here is the SQL Fiddle
Something like:
DECLARE #CandidateID INT = 1;
with cj as
(
select cs.CandidateId,
jr.JobId,
count(*) over (partition by jr.JobId, cs.CandidateId) skillsPosessed,
(select count(*) from JobRequirements where JobId = jr.JobId) skillsRequired
from CandidatesSkills cs
join JobRequirements jr
on cs.SkillId = jr.SkillId
)
select distinct cj.CandidateId, cj.JobId
from cj
where cj.skillsPosessed = cj.skillsRequired
In this case, you doing relational division with multiple divisors. In other words, you are dividing each set of JobRequirements per each JobID, by the CandidateSkills of that candidate.
In this case, a LEFT JOIN solution is much simpler
DECLARE #CandidateID INT = 1;
SELECT jr.JobID
,Skills = COUNT(c.SkillID)
,Requirements = COUNT(*)
FROM dbo.JobRequirements AS jr
LEFT JOIN dbo.CandidatesSkills AS c ON c.SkillID = jr.SkillID
AND c.CandidateID = #CandidateID
GROUP BY jr.JobID
HAVING COUNT(*) = COUNT(c.SkillID);
What this does is left-join the candidate's skills to the requirements. We then simply count up all the Requirements for the JobID, and ensure it is equal to the number of matches.
Another way to write this is
HAVING COUNT(CASE WHEN c.SkillID IS NULL THEN 1 END) = 0;
In other words: the number of non-matches should be zero.
SQL Fiddle

Find the average and total revenue by each sub-category for the categories which are among top 5 categories in terms of quantity sold? <SQL Server>

For this question, I have two tables and are as follows :
prod_cat_info --- This table has the following columns:
prod_cat : It contains the products' category names
prod_cat_id : It contains the products' category ID. Note that every product category has been assigned a unique ID. For example :: Lets say I have following product categories Books,Sports,Electronics. So these 3 product categories will be assigned product category ID as 1,2 & 3 respectively.
prod_subcat : It contains products' subcategories
prod_subcat_id : It contains products' subcategories ID
Now how this product subcategories are stored. For example : Lets say for product category "Books", I have 3 product subcategories like "Novels", "Schoolbooks" & "Fiction". So in this case also, each and every product subcategory would be assigned an ID like 1,2,3 and so on.
Transactions --- This is another table which has the following columns :
total_amt : It contains amount paid by customer when a transaction took place.
Qty : It contains quantities ordered by customer of a particular product.
prod_subcat_id : It contains products' subcategories ID
prod_cat_id : It contains the products' category ID.
Cust_ID : It contains customer ID [Irrelevant column in case of this question]
What I did is, I break this question into 2 parts & wrote 2 separate queries. Query is given below. I am not able to figure out how to join these 2 queries in order to achieve the output.
For my query1 - I have fetched all the product subcategories.
In query2 - I have fetched the top 5 product categories based on quantities sold.
Now I feel that Query2 can be used as a subquery in Query1 inside WHERE clause.
But It may require some modifications because what I know is that orderby can't be used in subquery & also result of a subquery will be a single output.
Therefore, I need some help on how can I combine/modify this query in order to achieve the result.
**Query1**
select P.prod_subcat as Product_SubCategory,
AVG(cast(total_amt as float)) as Average_Revenue,
SUM(cast(total_amt as float)) as Total_Revenue
from Transactions as T
INNER JOIN prod_Cat_info as P
ON T.prod_cat_code = P.prod_cat_code AND T.prod_subcat_code =
P.prod_sub_cat_code
group by P.prod_subcat
**Query2**
select top 5 P.prod_cat, sum(Cast(Qty as int)) AS Quantities_sold from
prod_cat_info as P
inner join Transactions as T
ON P.prod_cat_code = T.prod_cat_code AND P.prod_sub_cat_code =
T.prod_subcat_code
group by P.prod_cat
order by sum(Cast(Qty as int)) desc
If you have a TOP operator with ORDER BY, which is exactly your case, then you can use order by in a subquery. Because in this case the ORDER BY is used to determine the rows returned by the TOP clause.
And for multiple values you can use IN operator
select P.prod_subcat as Product_SubCategory,
AVG(cast(total_amt as float)) as Average_Revenue,
SUM(cast(total_amt as float)) as Total_Revenue
from Transactions as T
INNER JOIN prod_Cat_info as P
ON T.prod_cat_code = P.prod_cat_code AND T.prod_subcat_code =
P.prod_sub_cat_code
WHERE P.prod_cat_code IN (
select top 5 P.prod_cat_code
from prod_cat_info as P
inner join Transactions as T
ON P.prod_cat_code = T.prod_cat_code AND P.prod_sub_cat_code =
T.prod_subcat_code
group by P.prod_cat
order by sum(Cast(Qty as int)) desc
)
group by P.prod_subcat
Select prod_cat, prod_subcat , avg(total_amt) as average_amount , sum(total_amt) as total_amount
From transactions as t
inner join prod_cat_info as p
on t.prod_subcat_code=p.prod_sub_cat_code and t.prod_cat_code = p.prod_cat_code
Where prod_cat in
(Select Top 5 prod_cat
From transactions as t
inner join prod_cat_info as p
on t.prod_subcat_code=p.prod_sub_cat_code and t.prod_cat_code = p.prod_cat_code
Where total_amt > 0 and qty > 0
Group by prod_cat
Order by count(qty) desc)
Group by prod_subcat
Order by prod_cat asc;

SQL Inner join show numeric value once

I know my question is not very logical but I have the folowing chalenge:
HeadTab (Uniq_Id N(10)
Name C(30)
Tax N(18,2))
TrsTab (Uniq_Id N(10)
MonthlyDesc C(20)
Amount N(18,2))
What I want is the following select * from headtab inner join Trstab on uniq_id = Uniq_id
the issue is that I want to see the tax field only once per name other related should be 0...(Eventhough I have many lines in the details tab).
Thank you for any help
If you give the query a row number to determine the first row for each Name you can use a case statement to select which value you want for Tax.
SELECT
ht.Uniq_ID,
ht.NAME,
(CASE WHEN ROW_NUMBER() OVER (PARTITION BY ht.NAME ORDER BY ht.Uniq_ID) = 1 THEN ht.Tax ELSE 0 END) Tax,
tt.*
FROM
headtab ht
INNER JOIN Trstab tt ON ht.uniq_id = tt.Uniq_id

SQL: Select a column independent of where clause

SELECT TOP 1000 p.Title,p.Distributor, SUM(r.SalesVolume) AS VolumeOfSales,
CAST(SUM(r.CustomerPrice*r.SalesVolume) as decimal (18,0)) AS ValueOfSales,
CAST (AVG(r.CustomerPrice) as decimal (18,1)) AS AvgPrice,
p.MS_ContentType AS category ,Min(c.WeekId) AS ReleaseWeek
from Product p
INNER JOIN RawData r
ON p.ProductId = r.ProductId
INNER JOIN Calendar c
ON r.DayId = c.DayId
WHERE c.WeekId BETWEEN ('20145231') AND ('20145252')
AND p.Distributor IN ('WARNER', 'TF1', 'GAUMONT')
AND p.VODEST IN ('VOD', 'EST')
AND p.ContentFlavor IN ('SD', 'HD', 'NC')
AND p.MS_ExternalID1 IN ('ADVENTURE/ACTION', 'ANIMATION/FAMILY', 'COMEDY')
AND p.MS_ContentType IN ('FILM', 'TV', 'OTHERS')
AND r.CountryId = 1
GROUP BY p.Title,p.Distributor,p.MS_ContentType
ORDER BY VolumeOfSales DESC, ValueOfSales DESC
I want to madify the above query so that only the column ReleaseWeek is independent of the where clause WHERE c.WeekId BETWEEN ('20145231') AND ('20145252')
The result that I dervive looks like:
`Title Distributor VolumeOfSales ValueOfSales AvgPrice category ReleaseWeek
Divergente M6SND 94038 450095 4.0 Film 20145233`
However what I really want is the ReleaseWeek to be the first value in the column c.WeekId corresponding to that Titlein the database and not the first one between ('20145231') AND ('20145252') What is the best way to modify it? Any leads would be greatful.

Is this the only way to filter the right table in a left outer join?

I have customer balances stored in their own table. the customer balances table gets a new set of records every day (reflecting the balance that day) but contains balances for other days (yyyy-mm-dd). I wanted to get all UK customers from accountinformation and their balances yesterday from balances. I wanted to include rows from accountinformation even where there is no corresponding record (for yesterday) in balances...
select firstname,lastname,accountnumber,balance from accountinformation i
left outer join balances b
on i.accountnumber = b.account
where country = 'UK' and status = 'OPEN'
and (b.date = '2014-04-10' or b.date is null)
... it did not satisfy the requirement to show rows from accountinformation if there is no corresponding row in balances. I had to write the query like this...
select firstname,lastname,accountnumber,balance from accountinformation i
left outer join (select * from balances where date = '2014-04-10') b
on i.accountnumber = b.account
where country = 'UK' and status = 'OPEN'
.. to get the desired behavour. In the interests of correctness I want to know if there is a more correct way to filter the left table in a left outer join?
you might be able to do
select firstname,lastname,accountnumber,balance from accountinformation i
left outer join balances b
on i.accountnumber = b.account and b.date = '2014-04-10'
where country = 'UK' and status = 'OPEN'

Resources