Getting table data with total counts - mysql

I am having follwoing table
student
sid sname branch semester
1 Vijay CSE 6
2 Ajay MECH 4
3 Riteh CSE 6
4 Nutan CSE 6
5 Riya ETC 4
6 Ritu CSE 6
Here I want to fetch all record and total fetched record count for that i am using following query, but this is not able to fetch all records
select *,count(sid) from students
How can we do this

There are many possible solutions for this,
using subquery
select *,(SELECT COUNT(*) FROM students) totalCOunt from students
using CROSS JOIN
select a.*, b.totalCOunt
from students a, (SELECT COUNT(*) totalCOunt FROM students) b

Try this.
SELECT TotalRecords=Count(*) OVER(), Sname,Branch,Semester
FROM Students

Related

How can I get how many ocurrences are of an event over the event's own mean?

I have a table with grades:
name grade
peter 10
paul 8
mary 7
peter 6
mary 10
paul 5
paul 7
paul 6
mary 2
I would like to count how many grades does each of one have above their own mean.
For example, Peter has two grades, so Peter's mean is 8. Mary has 3 grades, but only 2 are above her own mean. Paul, has 4 grades, but only 2 are above his own mean. I would like to get as result something like:
name count
peter 1
mary 2
paul 2
I tried to do this using subqueries or adding a condition inside a count() column, but I usually get an error that tells me that my subquery returns more than 1 result. How can I achieve this?
Here is one of my attempts:
with staging as (
select name, count(*) as total,MAX(grade) as max_g, MIN(grade) as min_g, AVG(grade) as avg, STD(grade) as std
from students
where course = 'stats'
group by name)
select name,count(IF(grade > (select avg from staging),1,0)) as grades_over_mean from students
GROUP BY name
You can use window functions:
select s.*,
sum(grade > avg_grade) as num_above_average
from (select s.*,
avg(grade) over (partition by name) as avg_grade
from students s
) s;

count() results without using group by

I am attempting something very similar to last example (Using GROUP BY) on this page:
https://thecodedeveloper.com/mysql-count-function/
Referring to the following table of data:
id name salary department
1 Tom 4000 Technology
2 Sam 6000 Sales
3 Bob 3000 Technology
4 Alan 8000 Technology
5 Jack 12000 Marketing
The following query:
SELECT department, COUNT(*) AS "Number of employees"
FROM employees
GROUP BY department;
Will produce the following output:
department Number of employees
Marketing 1
Sales 1
Technology 3
Except I want to see the number of employees in each department as well as every user in the table.
So I want the output to look like this:
id name salary department employees per department
1 Tom 4000 Technology 3
2 Sam 6000 Sales 1
3 Bob 3000 Technology 3
4 Alan 8000 Technology 3
5 Jack 12000 Marketing 1
I have managed to achieve what I want using a second query to test every result from the first query but it is extremely slow and I am convinced that there is a faster way to do it in a single query.
That's a window count. In MySQL 8.0:
select e.*, count(*) over(partition by d.department) as number_of_employees
from employees e
In earlier versions, an alternative uses a correlated subquery:
select e.*,
(select count(*) from employees e1 where e1.department = e.department) as number_of_employees
from employees e

How to select one column with all distinct values based on some clause

I essentially like to have one query which I'll execute one time and like to have the result (no multiple query execution) and definitely, the query should use simple MySQL structure (no complex/advanced structure to be used like BEGIN, loop, cursor).
Say I've two tables.
1st Table = Country (id(PK), name);
2nd Table = Businessman (id(PK), name, city, country_id(FK))
Like to SELECT all countries, whose businessmen are from distinct cities. No two businessmen exist in one country, who are from the same city. If so, that country will not be selected by the SELECT clause.
Country
id name
1 India
2 China
3 Bahrain
4 Finland
5 Germany
6 France
Businessman
id name city country_id
1 BM1 Kolkata 1
2 BM2 Delhi 1
3 BM3 Mumbai 1
4 BM4 Beijing 2
5 BM5 Paris 6
6 BM6 Beijing 2
7 BM7 Forssa 4
8 BM8 Anqing 2
9 BM9 Berlin 5
10 BM10 Riffa 3
11 BM11 Nice 6
12 BM12 Helsinki 4
13 BM13 Bremen 5
14 BM14 Wiesbaden 5
15 BM15 Angers 6
16 BM16 Sitra  3
17 BM17 Adliya 3
18 BM18 Caen 6
19 BM19 Jinjiang 2
20 BM20 Tubli 3
21 BM21 Duisburg 5
22 BM22 Helsinki 4
23 BM23 Kaarina 4
24 BM24 Bonn 5
25 BM25 Kemi 4
In this respect, China and Finland shouldn't be listed.
I've attempted using count and group by, but no luck.
Can you please help me to build up this query.
Here it is, all you need is to join Businessman table and count cities and distinct cities and if they equal that means all businessmen are from different cities:
SELECT
c.`id`,
c.`name`,
COUNT(b.`id`) AS BusinessmanCount,
COUNT(b.`city`) AS CityCount,
COUNT(DISTINCT b.`city`) AS DistinctCityCount
FROM `countries` c
INNER JOIN Businessman b ON c.`id` = b.`country_id`
GROUP BY c.`id`
HAVING CityCount = DistinctCityCount
For minified version what you exactly need:
SELECT
c.`id`,
c.`name`
FROM `countries` c
INNER JOIN Businessman b ON c.`id` = b.`country_id`
GROUP BY c.`id`
HAVING COUNT(b.`city`) = COUNT(DISTINCT b.`city`)
Well, I think we should have waited for you to show your own query, because one learns best from mistakes and their explanations. However, now that you've got answers already:
Yes, you need group by and count. I'd group by cities to see if I got duplicates. Then select countries and exclude those that have duplicate cities.
select *
from country
where id not in
(
select country_id
from businessmen
group by city, country_id
having count(*) > 1
);
You need either nested aggregations:
select *
from Country
where id in
(
select country_id
from
(
select city, country_id,
count(*) as cnt -- get the number of rows per country/city
from Businessman
group by city, country_id
) as dt
group by country_id
having max(cnt) = 1 -- return only those countries where all counts are unique
)
Or compare two counts:
select *
from Country
where id in
(
select country_id
from Businessman
group by country_id
having count(*) = count(distinct city) -- number of cities is equal to umber of rows
)

mysql group by on sum column

I am having a scenario where students of a college do a research on a subject. Each subject has some value (marks) for it. A student can do research on multiple subjects.
I have the following table hierarchy:
student (s)
---------------
student_id subject_id
1 2
2 1
2 3
3 1
3 3
4 2
4 3
.....
research_subjects (r)
-----------------------------
id value
1 5
2 10
3 20
4 40
....
Now i am fetching the student records along with their total research value with this query:
select student_id, sum(r.value) as total from student s inner join research_subjects r on s.subject_id=r.id group by student_id
This gives results like the following:
student_id total
1 10
2 25
3 25
4 30
As you see, the results are grouped by student_id. But what i want is to group the results by total value. So i want to get rid of duplicate rows for the total, in the output. (i.e., have only 1 record with the total=25).
I tried using: group by total in the query (instead of group by student_id), but it gives an error.
Is there any other way of grouping the results by the column that contains 'sum' value?
Try this:
select count(student_id), total
from (
select student_id, sum(r.value) as total
from student s
inner
join research r on s.subject_id=r.id group by student_id
) s2
group by total
Try this:
select Count(student_id) as students, total
from
(
select student_id, sum(r.value) as total
from student s inner join research r on s.subject_id=r.id
group by student_id
) s
group by total
Or this:
select Min(student_id) as student_id, total
from
(
select student_id, sum(r.value) as total
from student s inner join research r on s.subject_id=r.id
group by student_id
) s
group by total

SELECT sql with four different tables with primary key and foreign key

For my database, having these four table
First one, DEPARTMENT
//DEPARTMENT
D# DNAME
------------------
1 RESEARCH
2 IT
3 SCIENCE
Second one, EMPLOYEE
//Employee
E# ENAME D#
-----------------------
1 ALI 1
2 SITI 2
3 JOHN 2
4 MARY 3
5 CHIRS 3
Third, PROJECT
//PROJECT
P# PNAME D#
-----------------------
1 Computing 1
2 Coding 3
3 Researching 3
Fourth, WORKSON
//WORKSON
E# P# Hours
--------------------
1 1 3
1 2 5
4 3 6
So my output should be something like
E# ENAME D# TOTAL HOURS/W
--------------------------------------------
1 ALI 1 8
2 SITI 2 0
3 JOHN 2 0
4 MAY 3 6
5 CHIRS 3 0
Display 0 because the employee has no project to works on.
my currently statement using
SELECT E#,ENAME,D# and sum(Hours) as TOTAL HOURS/W
FROM EMPLOYEE,PROJECT,WORKSON
WHERE EMPLOYEE.P#
no idea how should it select
You should use an left join like this. You only need 2 tables employee and workson.
Try this query:
SELECT e_tbl.E#, e_tbl.ENAME, e_tbl.D#,
coalesce(SUM(w_tbl.Hours), 0) as "Total Hours/W"
FROM
EMPLOYEE e_tbl LEFT JOIN WORKSON w_tbl
ON e_tbl.E# = w_tbl.E#
GROUP BY e_tbl.E#
You need to use GROUP BY and JOINS , in order to achieve your output
SELECT E.E#,
E.ENAME,
E.D#,
sum(Hours) AS TOTAL HOURS/W
FROM Employee AS E
JOIN WORKSON AS W ON E.E# = W.E#
GROUP BY E.E#,
E.ENAME,E.D#
Use this :)
With the given output you do not need to join all the tables, and this could be done by joining employee and works on as
select
e.`E#`,
e.ENAME,
e.`D#`,
coalesce(tot,0) as `TOTAL HOURS/W`
from Employee e
left join
(
select `E#`,
sum(Hours) as tot
from WORKSON
group by `E#`
)w
on w.`E#` = e.`E#`
group by e.`E#`
DEMO