Count the number of repetitions for one column - mysql

I am unable to successfully write this query and have not yet found any resources.
I have a table with two columns. The table looks a bit like this:
|student|teacher|
| 5314 | 656 |
| 4189 | 671 |
| 4506 | 671 |
| 4515 | 671 |
| 3754 | 756 |
| 3760 | 756 |
| 1066 | 781 |
I want the result set to look like this:
|teacher|count|
| 656 | 1 |
| 671 | 3 |
| 756 | 2 |
| 781 | 1 |
Any hint is really appreciated.

You want to use the COUNT(*) aggregate function here, and group by the teacher column.
Try this:
SELECT teacher, COUNT(*) as numStudents
FROM myTable
GROUP BY teacher;
This will group all rows from your table by teacher, and count the number of rows in that group (effectively counting the number of students).
Here is more on Aggregate Functions for you.

Related

Left joins, i need an explanation about a code

i am watching a tutorial. There is a code which i don't understand what is supposed to do.
$sql = 'SELECT p.*,
a.screen_name AS author_name,
c.name AS category_name
FROM
posts p
LEFT JOIN
admin_users a ON p.author_id = a.id
LEFT JOIN
categories c ON p.category_id = c.id
WHERE
p.id = ?';
I read about the left joins but i didn't understand them. Can somebody please explain me the code i shared.
Thanks in advance!
Imagine you have two tables. One that stores the information about the programmers on your website, and the other table that keeps track of their online purchases.
PROGRAMMERS Table
+--------------------------------------------+
| ID | NAME | AGE | ADDRESS | SALARY |
+----+----------+-----+-----------+----------+
| 1 | Desire | 32 | 123 fake s| 3000.00 |
| 2 | Jamin | 25 | 234 fake s| 2500.00 |
| 3 | Jon | 23 | 567 fake s| 2000.00 |
| 4 | Bob | 30 | 789 fake s| 1500.00 |
| 5 | OtherGuy | 31 | 890 fake s| 1000.00 |
| 6 | DudeMan | 32 | 901 fake s| 500.00 |
+--------------------------------------------+
PURCHASES Table
+---------------------------------------------+
| ORDER_ID | PROG_ID | DATE | PRICE |
+-------------+---------+---------------------|
| 1 | 1 | 1-1-2017 | 100 |
| 2 | 2 | 1-2-2017 | 200 |
| 3 | 6 | 1-3-2017 | 300 |
+---------------------------------------------|
You decide you need to make a new table to consolidate this information to a table that contains
certain columns you want.
For example, you figure it would be nice for shipping purposes to have a table
that has the ID, the NAME, the PRICE, and the DATE columns.
Currently, the tables we have don't display all of that in a single table.
If we were to LEFT JOIN these tables, we would end up filling the desired columns
with NULL values where there is no information to join.
SELECT ID, NAME, PRICE, DATE
FROM PROGRAMMERS
LEFT JOIN PURCHASES
ON PROGRAMMERS.ID = PURCHASES.PROG_ID;
Notice that I'm selecting the columns I want from the starting table, then joining the right table
even though there might be missing information.
RESULTING TABLE
+-------------------------------------+
| ID | NAME | PRICE | DATE |
+----+----------+-----------------+---+
| 1 | Desire | 100 | 1-1-2017 |
| 2 | Jamin | 200 | 1-2-2017 |
| 3 | Jon | NULL | NULL |
| 4 | Bob | NULL | NULL |
| 5 | OtherGuy | NULL | NULL |
| 6 | DudeMan | 300 | 1-3-2017 |
+-------------------------------------+
For a visual representation of the difference between SQL JOINs check out
https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins .

Update with results of Ordered Select into Column

I have a simple table with four columns: id | name | score | rank that looks like this:
id | name | score | rank
---|------|-------|-----
1 | Bob | 99 | -
2 | Jim | 88 | -
3 | Rex | 103 | -
4 | Zus | 55 | -
I'd like to sort these rows by score (descending) and store the approriate ranking in the rank column for each row.
Currently, I'm using the following code to create an alias column that has the rankings:
SET #rank:=0;
SELECT *, #rank:=#rank+1 AS rank_test FROM test ORDER BY score DESC
Which returns:
id | name | score | rank | rank_test
---|------|-------|------|----------
3 | Rex | 103 | - | 1
1 | Bob | 99 | - | 2
2 | Jim | 88 | - | 3
4 | Zus | 55 | - | 4
How can I transfer the result of the rank_test alias into the rank column?
I've researched a lot of answers but can't seem to get anything to work. Fairly new to SQL so I apologize if it's a simple solution. Thank you!

How to find missing time value(s) in a given range in MySQL database?

Let's say I have a table like this:
| id | mtime |
...
| 101 | 12:00:00 |
| 102 | 12:01:00 |
| 103 | 12:03:00 |
| 104 | 12:07:00 |
| 105 | 12:08:00 |
| 106 | 13:00:00 |
...
Is there a way to query the table (range 12:00:00-13:00:00) to get a set with missing values like this:
| mtime |
| 12:02:00 |
| 12:04:00 |
| 12:05:00 |
| 12:06:00 |
| 12:09:00 |
| 12:10:00 |
...
| 12:59:00 |
or at least first empty occurance:
| mtime |
| 12:02:00 |
or last consecutive value, that breaks the chain:
| mtime |
| 12:01:00 |
I was thinking about using ADDTIME(time, '00:01:00') somewhere in the query but I can't figure it out. Right now I barely believe it's achievable without more complex coding and multiple queries, but I hope I'm missing something.
Generate a table (TABLE2) which have time of a full day (if u really need at any date),
and write your query like this
SELECT TABLE2.mtime FROM TABLE2
LEFT JOIN TABLE1 ON TABLE1.mtime = TABLE2.mtime
WHERE TABLE1.mtime IS NULL
also add condition for maximum and minimum time check, because TABLE2 have all dat times.

How to do multiple SUM statements in a single SQL query?

I'm pretty new to SQL and I need to figure out how to run multiple sums in the same statement. For example, imagine you have a table something like this...
+----+---------------+-------------+------------+-----------+
| id | name | order_num | cost | company |
+----+---------------+-------------+------------+-----------+
| 1 | John Smith | 0 | 10.00 | CompanyA |
| 2 | Sally Thomas | 1 | 38.00 | CompanyA |
| 2 | Sally Thomas | 2 | 12.00 | CompanyA |
| 1 | John Smith | 3 | 19.00 | CompanyA |
| 2 | Jimmy John | 4 | 40.00 | CompanyB |
+----+---------------+-------------+------------+-----------+
I would like to write a query that returns the name and total sum spent for each customer at CompanyA. So basically...
+---------------+------------+
| name | total |
+---------------+------------+
| John Smith | 29.00 |
| Sally Thomas | 50.00 |
| Jimmy John | 0.00 |
+---------------+------------+
To do that I know I'm going to need to use the sum function. But everything I've tried so far results in summing up the entire column rather than the individual parts for each person. This is just a simplified example of the bigger table I'm doing this on, so I don't know any of the field data beforehand. How can I do multiple sums in one query to get this result? Thanks!
Also, I'm using MySQL if it matters.
I think you want:
select name, sum(case when company = 'CompanyA' then cost else 0 end) as Total
from t
group by name;

Is it possible to create calculation rows from query results in MySQL?

I am trying to find a way to output a calculation row (or two) of an SQL search query, so I may see the raw results along with a calculation associated to them, either above or under the listing of raw results. For instance, I have the following data:
mysql> select * from data [where condition];
+----+--------+-----+--------+
| id | height | age | weight |
+----+--------+-----+--------+
| 1 | 65.2 | 45 | 45.23 |
| 2 | 63.1 | 47 | 0 |
| 3 | 59.2 | 37 | 38.1 |
| 4 | 59.8 | 39 | 36.4 |
| 5 | 63.4 | 37 | 38.1 |
| 6 | 72.1 | 34 | 2 |
| 7 | 100 | 50 | 20 |
+----+--------+-----+--------+
And what I want is to be able to perform any query to get all or a subset of this data, but have the resulting table give something like the following (with the summary/calculation output separate from the raw data, such as either above or below it):
mysql> query???
+--------+--------+------+--------+
| id | height | age | weight |
+--------+--------+------+--------+
| 1 | 65.2 | 45 | 45.23 |
| 2 | 63.1 | 47 | 0 |
| 3 | 59.2 | 37 | 38.1 |
| 4 | 59.8 | 39 | 36.4 |
| 5 | 63.4 | 37 | 38.1 |
| 6 | 72.1 | 34 | 2 |
| 7 | 100 | 50 | 20 |
+--------+--------+------+--------+
| STDDEV | 13.26 | 5.57 | 17.15 |
| COUNT | 7 | 7 | 7 |
| etc. | etc. | etc. | etc. |
+--------+--------+------+--------+
I've found some approaches such as this (http://www.sqlservercurry.com/2011/06/sql-server-row-summary-column-summary.html) that somewhat do it, but because the calculation acts on all rows it doesn't work well for some calculations (for instance, using stddev results in "0" for everything except the calculation row).
I can create a separate result of calculations such as the following, but it would be nice to have them somehow combined, such as shown above. In addition, the following only outputs one row of calculations, and it would be nice to have several rows of pertinent calculations.
select stddev(height), stddev(age), stddev(weight) from data [where condition];
The point here is to perform any search query and get an auto-generated preview of basic descriptive information from the results (deviations, counts, mean, etc.). Hopefully this can be done directly in SQL, without needing to use another language/API.
Combine your results with union. If you need the results in a particular order, then create a column containing the precedence and order by that column.
select id, height, age, weight, 0 sortorder
from data [where condition]
union all
select 'stdev count', stddev(height), stddev(age), stddev(weight), 1
from data [where condition]
order by sortorder