Mysql group by join wrong result [duplicate] - mysql

This question already has answers here:
SQL select only rows with max value on a column [duplicate]
(27 answers)
Retrieving the last record in each group - MySQL
(33 answers)
Closed 4 months ago.
I not figure out to evaluate the maximum creation date value in a join. Below the tables envolved:
Supervisor
SupervisorCompany
Company
A Supervisor can be related to many Company, and a Company can be related to many Supervisor.
The relation ManyToMany is represented by SupervisorCompany table that conatains the foreign key related.
--------------
| Supervisor |
-----------------------------------------------------------
IdSupervisor | Name | Surname | CreationTime |
------------------------------------------------------------
1 | Maximilian | Green | 2022-01-01 01:00:01 |
------------------------------------------------------------
2 | Josh | Nice | 2023-04-03 01:00:01 |
------------------------------------------------------------
3 | Albert | Cloud | 2022-03-01 01:32:01 |
------------------------------------------------------------
4 | Peter | Dark | 2022-03-01 01:32:01 |
------------------------------------------------------------
--------------
| Company |
--------------------------------------
IdCompany | Brand | Address |
--------------------------------------
1 | X | |
--------------------------------------
2 | Y | |
--------------------------------------
3 | Z | |
--------------------------------------
4 | J | |
--------------------------------------
-------------------------
| SupervisorCompany |
--------------------------------------
Id |Id_Supervisor | Id_Company |
--------------------------------------
8 | 1 | 1 |
--------------------------------------
9 | 2 | 1 |
--------------------------------------
10 | 3 | 1 |
--------------------------------------
11 | 4 | 3 |
--------------------------------------
I want return the newest CreationTime Supervisor of a Company for each Company.
I executed this query:
select *, MAX(Supervisor.CreationTime) from Company
inner join SupervisorCompany on Company.IdCompany = SupervisorCompany.IdCompany
inner join Supervisor on SupervisorCompany.IdSupervisor = Supervisor.IdSupervisor
GROUP BY Company.IdCompany;
But the result is:
| Maximilian | Green | 2022-01-01 01:00:01 | 1 |
insted
| Josh | Nice | 2023-04-03 01:00:01 | 1 |
I know that there is somethings wrong in the query but I don't know exactly what is the mistake.
I tried with a subquery or others approach but I don't figure out.
Thanks in advance

You should select only the company ID and the max creation time:
SELECT c.IdCompany, MAX(s.CreationTime) AS MaxCreationTime
FROM Company c
INNER JOIN SupervisorCompany sc ON c.IdCompany = sc.IdCompany
INNER JOIN Supervisor s ON sc.IdSupervisor = s.IdSupervisor
GROUP BY c.IdCompany;
The rough rule of thumb for an aggregation query is that we can select only columns which appear in the GROUP BY clause or columns which appear inside aggregate functions (such as MAX()).

Related

How to get records from below tables

I have 3 tables
QUESTION table with below 2 properties
1. ID (serial)
2. Question (varchar)
ANSWER table with below 4 properties
1. ID (serial)
2. QuestionID (foreign key to table QUESTION)
3. StudentID (foreign key to table STUDENT)
4. ANSWER (varchar)
5. SubmitDateTime (datetime)
STUDENT table with below properties
1. ID (serial)
2. Name (varchar)
I just want to show records with each student (one record for each student) with every answer. If any question's answer is not given by the student it will show blank.
For example:
QUESTION TABLE
| ID | QUESTION |
|----- | --------- |
| 1 | A FOR? |
| 2 | B FOR? |
| 3 | C FOR? |
ANSWER TABLE
| ID | QuestionID | StudentID | ANSWER | SubmitDateTime |
|----- | ----------- |------------|--------|----------------|
| 1 | 1 | 1 |Apple | something date |
| 2 | 1 | 2 |Ant | something date |
| 3 | 2 | 1 |Book | something date |
| 4 | 3 | 2 |Cat | something date |
STUDENT TABLE
| ID | NAME |
|----- | --------- |
| 1 | Jhon |
| 2 | Lily |
Expected Records
Result table
| ID | NAME | Answers |
|----- | --------- | ---------------------|
| 1 | Jhon | Apple,Book,<blank> |
| 2 | Lily | Ant,<blank>,Cat |
"blank" means no record will be shown instead of a blank space or a hyphane.
My implementation:
SELECT s.ID,s.Name,
GROUP_CONCAT(a.answer SEPARATOR ',') AS answers
FROM student AS s
LEFT JOIN answer AS a ON a.studentID=s.ID
WHERE a.submitdate BETWEEN '<somedate>' AND '<somedate>'
GROUP BY s.ID ORDER BY a.ID ASC
It does not give me a blank answer. How to get these?
Try this:
SELECT sid, sname, GROUP_CONCAT(IFNULL(a.answer,'-') ORDER BY qid)
FROM
(SELECT q.id AS qid, s.id AS sid, s.Name AS sname
FROM question q CROSS JOIN student s) qs
LEFT JOIN answer a ON qs.qid=a.QuestionID AND qs.sid=a.StudentID
GROUP BY sid, sname;
The base query is a CROSS JOIN between question and student tables that will be a subquery and give a result like this:
+-----+-----+-------+
| qid | sid | sname |
+-----+-----+-------+
| 1 | 2 | Lily |
| 1 | 1 | Jhon |
| 2 | 2 | Lily |
| 2 | 1 | Jhon |
| 3 | 2 | Lily |
| 3 | 1 | Jhon |
+-----+-----+-------+
As you can see, each of the student will be paired with all of the existing question regardless of their answer records in answer table. This will be the reference for the LEFT JOIN with answer table.
Demo fiddle

Join 3 tables up count the highest user in one table

I'm trying 3 join tables so i can report who has the highest calls for each single customer please see the tables below
+-------+--+------------+
| users | | |
+-------+--+------------+
| id | | first name |
| 1 | | Bill |
| 2 | | Ben |
| 3 | | Bob |
| 4 | | Barry |
+-------+--+------------+
the second table is a call customers table
+-----------+--+-------------------+
| customers | | |
+-----------+--+-------------------+
| id | | Company |
| 1 | | windows company |
| 2 | | glass company |
+-----------+--+-------------------+
the third table is the where to calls are record
+-------------+--+--------+--------------+
| callrecords | | | |
+-------------+--+--------+--------------+
| id | | userid | company id |
| 1 | | 1 | 1 |
| 2 | | 1 | 1 |
| 3 | | 1 | 1 |
| 4 | | 2 | 1 |
| 5 | | 2 | 2 |
| 6 | | 2 | 2 |
+-------------+--+--------+--------------+
So as you can see in the call record table company id 1 which is the windows company has had 4 calls but user 1 made the most so that company i need to display bill company id 2 which is the glass company need to display user id 2 because they made 2 calls in total and not user id 1 because they only made 1 call
so the mysql query i need to make needs to loop round so the report looks like this
windows company - most calls bill
glass company - most calls Ben
If you want a single query that will fetch records. You can check below query. This will give you highest calls for each single customer.
SELECT CR.companyid, C.company, U.first_name, COUNT(CR.userid) AS callCount
FROM callrecords AS CR
INNER JOIN customers AS C ON (C.id= CR.companyid)
INNER JOIN users AS U ON (U.id= CR.userid)
GROUP BY C.id,CR.userid HAVING callCount = (
SELECT count(callrecords.userid) as count
FROM callrecords
WHERE callrecords.companyid = CR.companyid
GROUP BY callrecords.userid
ORDER BY count DESC
LIMIT 1
);
Ignore spells of table or column name because table's or column's name in question is not well formatted.

Select a single row when item categorised in two specific categories [MySql] [duplicate]

This question already has answers here:
Select values that meet different conditions on different rows?
(6 answers)
Closed 4 years ago.
can I return a single instance of a row after using a join on a categories table.
Entries
| id | Name |
| 1 | Johnny |
| 2 | Steve |
| 3 | Bam |
Categories
| cat_id | Name |
| 1 | Season one |
| 2 | Season two |
| 3 | Season three|
Category Posts
| id | cat_id |
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 2 |
| 2 | 3 |
| 3 | 1 |
What I want to do is select all cast where members that have been in season 2 and 3, they must have been in both and I only want a single instance returned.
Expected output
| id | Name |
| 1 | Johnny |
| 2 | Steve |
How would I got about selecting these? I've thought about grouping the user based on their name however because I'm selecting IN ("2", "3") I get some users that have been in two but not three and the expected results are wrong.
Thanks
you can use sub query
SELECT id,name from Entries where id in (select a.id from (select id from
category_post WHERE cat_id=2) as a,(select id from category_post WHERE cat_id=3) as b where a.id=b.id)

How can I return all results from one table combined with the count of a specific field of another? [duplicate]

This question already has answers here:
select from one table, count from another where id's linked
(2 answers)
Closed 4 years ago.
I have something like this:
TABLE: maindata
client_id | username | data | data_id
______________________________________
0 | rusty | xyz | 827
1 | rusty1 | xyz | 827
2 | rusty2 | xyz | 827
And then in another table I have:
TABLE: users:
client_id | username |
______________________
0 | rusty |
1 | rusty1 |
2 | rusty2 |
2 | rusty3 |
2 | rusty4 |
I would like to return:
client_id | username | data | data_id | count
______________________________________
0 | rusty | xyz | 827 | 1
1 | rusty1 | xyz | 827 | 1
2 | rusty2 | xyz | 827 | 3
The count here is the count for the number of clients in users. What I have tried has not gotten me where I would like at all:
SELECT * from stats AS s INNER JOIN users as u SELECT COUNT(*) WHERE
u.client_id=s.client_id GROUP BY client_id
Any idea where I am going wrong? Is INNER JOIN totally wrong?
Edit : highlight query.
I think you want
SELECT s.*, COUNT(*) as count from stats AS s
INNER JOIN users as u on u.client_id=s.client_id
GROUP BY client_id

MySQL Count Column [duplicate]

This question already has answers here:
How can I return pivot table output in MySQL?
(10 answers)
Closed 5 years ago.
I have the following db table, and I would like to be able to count amount of each product_id per name.
---------------------
| name | product_id |
---------------------
| David | 1 |
|Charlie| 1 |
| David | 2 |
| David | 1 |
|Charlie| 2 |
|Charlie| 3 |
|Charlie| 2 |
|Charlie| 3 |
---------------------
I would like to able to create a result set like the following;
----------------------------------------------------------------------------
| name | count(product_id_1) | count(product_id_1) | count(product_id_1) |
----------------------------------------------------------------------------
| David | 2 | 1 | 0 |
|Charlie | 1 | 2 | 2 |
----------------------------------------------------------------------------
So, please help me how to query for the above problem, Thank's
If you wan't to group the count of products based on customers you can do something like the following if you are joining tables.
SELECT
NAME,
COUNT(product_id1),
COUNT(product_id2),
COUNT(product_id2)
FROM
Customers c
INNER JOIN Ordered_Products
ON c.id = customer.id
GROUP BY c.name
otherwise if you're not doing a join you can do the following
SELECT
NAME,
COUNT(product_id1),
COUNT(product_id2),
COUNT(product_id2)
FROM
Customers c
GROUP BY c.name