Combining 2 Sql results rows - mysql

I have a query that get's a list of information from the answers table, it checks if the specific coach that is viewing the page has records with his coach_id in the answers table, and if other coaches have answers.
Now when there's more than 1 coach that has answers for 1 specific employee (werknemer_id) as you can see in the screenshot below, the field get's duplicated for that coach.
I'm wondering if it's possible to combine the 2 fields into 1 field..%aybe with comma seperated values? So i don't have a duplicate name in my result?
This is my code
SELECT l.id, l.naam, r.id AS revisie, r.beschrijving, w.id AS werknemer, w.voornaam, w.achternaam, a.coach_id,
CASE WHEN a.coach_id = 3 THEN 1 ELSE 0 END AS zelf_ingevuld,
CASE WHEN a.coach_id != 3 AND a.coach_id != 3 THEN (SELECT CONCAT(voornaam, ' ', achternaam) FROM coaches WHERE id = a.coach_id ) ELSE 0 END AS coach_ingevuld
FROM lijsten l
INNER JOIN revisies r ON l.id = r.lijst_id
INNER JOIN werknemerlijsten wl ON wl.lijst_id = l.id
INNER JOIN werknemers w ON w.id = wl.werknemer_id
INNER JOIN klanten k ON k.id = w.klant_id
LEFT JOIN antwoorden a ON w.id = a.werknemer_id AND r.id=a.revisie_id
LEFT JOIN coaches c ON c.id = a.coach_id
WHERE r.actief = 1
GROUP BY r.id, c.id, w.id
Thank you!

use SELECT CONCAT(table1.column_name, ',', table2.column_name) AS new_column_alias ...
this should give you the output you'll need in a comma separated field that you can name as you wish

Related

mysql query not giving accurate result

I am working on a query whose purpose is to get the records of all the students whose financialyear_id!=4 and don't dispaly records even if he/she has finacialyear_id other then 4 exist.
I have written a query but it gives me the record of that student whose finacialyear_id!=4 but I want to achieve that no records will be shown if financialyear_id=4 exist for any student.
SELECT a.id aid
, s.id sid
, s.name
, s.father_name
, s.cnic
, f.financialyear_id
FROM student s
JOIN academic_info a
ON a.s_id = s.id
LEFT
JOIN fee_issued f
ON a.id = f.academic_info_id
WHERE f.financialyear_id != 4
AND a.is_data_locked = 0
AND a.university_id = 60;
Foreign Key: s_id in both tables academic_info and fee_issued,academic_info_id in fee_issued table.
You used a keyword in your request: "but I want to achieve that no records will be shown if financialyear_id=4 exist for any student." So use EXISTS (or IN which does about the same) to check for existence.
As you are using MySQL you must write the select condition for academic_info twice. Other DBMS handle this more elegantly.
select a.id as aid, s.id as sid, s.name, s.father_name, s.cnic, f.financialyear_id
from student s
join academic_info a on a.s_id = s.id and a.is_data_locked = 0 and a.university_id = 60
left join fee_issued f on f.academic_info_id = a.id
where s.id not in
(
select ai.s_id
from academic_info ai
join fee_issued fi on fi.academic_info_id = ai.id and fi.financialyear_id != 4
where ai.is_data_locked = 0 and ai.university_id = 60
);
Above query also gets you students that have no fee_issued at all. If you want these removed, change the left join to an inner join.
EDIT: Here is the same with NOT EXISTS.
select a.id as aid, s.id as sid, s.name, s.father_name, s.cnic, f.financialyear_id
from student s
join academic_info a on a.s_id = s.id and a.is_data_locked = 0 and a.university_id = 60
left join fee_issued f on f.academic_info_id = a.id
where not exists
(
select *
from academic_info ai
join fee_issued fi on fi.academic_info_id = ai.id and fi.financialyear_id != 4
where ai.is_data_locked = 0 and ai.university_id = 60
and ai.s_id = s.id
);

MySQL query with and without WHERE condition at once

How can I select both values at once? For example, I have a Lesson that have Students and each Student is linked to a Client, so what I want to achieve is something like:
SELECT l.id,
l.value * clientStudents/totalStudents as total
FROM Lesson l
JOIN lesson_student ls ON l.id = ls.lesson_id
JOIN Student s ON ls.student_id = s.id
JOIN Client c ON s.client_id = c.id
**WHERE c.id = <SOME_CLIENT>**
being clientStudents the count using the WHERE clause and totalStudents without using it.
You can move the condition in the calculation phase. Something like:
SELECT l.id,
l.value * SUM(if(c.id = <SOME_CLIENT>,clientStudents,0)) / SUM(totalStudents) as total
FROM Lesson l
JOIN lesson_student ls ON l.id = ls.lesson_id
JOIN Student s ON ls.student_id = s.id
JOIN Client c ON s.client_id = c.id
GROUP BY l.id, l.value

Query goes wrong when checking if the user exists in other table

I have a query that shows a list of revisions and employees for every revision..
Now I'm trying to show if the given employee already has a row in the answers table..
This is the overview of the database
This is my working query that shows the list of revisions and employees
SELECT l.id, l.naam, r.id as revision_id, r.beschrijving, e.id as employee_id, e.voornaam, e.achternaam,
FROM lists l
INNER JOIN revisions r ON l.id = r.list_id
INNER JOIN employeelists el ON el.list_id= l.id
INNER JOIN employees e ON e.id = el.employee_id
INNER JOIN customers c ON c.id = e.customer_id
WHERE customer_id = :id AND r.actief = 1
Now I've tried several things to see if the employee already has a record in the answers table.. But It's failing the whole time..
Try 1 : Adding the Answers table with a left outer join
SELECT l.id, l.naam, r.id as revision_id, r.beschrijving, e.id as employee_id, e.voornaam, e.achternaam,
**CASE WHEN a.coach_id != 0 THEN 1 ELSE 0 END as FILLED IN**
FROM lists l"""
INNER JOIN revisions r ON l.id = r.list_id
**LEFT OUTER JOIN answers a ON a.revision_id = r.id**
INNER JOIN employeelists el ON el.list_id= l.id
INNER JOIN employees e ON e.id = el.employee_id
INNER JOIN customers c ON c.id = e.customer_id
WHERE customer_id = :id AND r.actief = 1
now the problem is that every employee is shown multiple times...
This is the SQLFiddle of the working database, The only thing i can't do is check if the given employee ( werknemer ) exists in the answers ( antwoorden ) table..
http://sqlfiddle.com/#!2/0c01c/4
Any idea on how i can solve this? I tried a subquery, but that didn't work out either.. Thanks!
Problem with Query Now
I thought i was correct but there's one more error. in the answers table, it shows results for werknemer_id ( employee_id ) = 78. For the revisie ( revision ) 1 and 2
While there is only results for revisie 1 (screenshot below)
Thanks!
How about this exist column will have 0 if not in antwoorden and 1 if exist
SELECT l.id, l.naam, r.revisie as revisie, r.id as revisie_id, r.beschrijving, w.id as werknemer, w.voornaam, w.achternaam
, a.werknemer_id,
(CASE WHEN a.werknemer_id IS NULL THEN 0 ELSE 1 END ) AS `exist`
FROM lijsten l
INNER JOIN revisies r ON l.id = r.lijst_id
INNER JOIN werknemerlijsten wl ON wl.lijst_id = l.id
INNER JOIN werknemers w ON w.id = wl.werknemer_id
INNER JOIN klanten k ON k.id = w.klant_id
LEFT JOIN antwoorden a ON w.id = a.werknemer_id
WHERE klant_id = 39 AND r.actief = 1
GROUP BY r.beschrijving, w.id
Fiddle
Final solution
This is the final outcome, only see 'ingevuld' is 1 if the desired coach (1 in thise case) is in the answers table.
SELECT l.id, l.naam, r.revisie AS revisie, r.id AS revisie_id, r.beschrijving, w.id AS werknemer, w.voornaam, w.achternaam, a.coach_id,
CASE WHEN a.coach_id = 1 THEN 1 ELSE 0 END AS ingevuld
FROM lijsten l
INNER JOIN revisies r ON l.id = r.lijst_id
INNER JOIN werknemerlijsten wl ON wl.lijst_id = l.id
INNER JOIN werknemers w ON w.id = wl.werknemer_id
INNER JOIN klanten k ON k.id = w.klant_id
LEFT JOIN antwoorden a ON w.id = a.werknemer_id AND r.id=a.revisie_id
WHERE klant_id = 39 AND r.actief = 1
group by r.id, w.id, a.coach_id

Rows missing from mysql pivot query results

I have a mysql query as stated below, it returns exactly the results I want for one row, but doesn't return any other rows where I expect there to be 8 in my test data (there are 8 unique test ids). I was inspired by this answer but obviously messed up my implementation, does anyone see where I'm going wrong?
SELECT
c.first_name,
c.last_name,
n.test_name,
e.doc_name,
e.email,
e.lab_id,
a.test_id,
a.date_req,
a.date_approved,
a.accepts_terms,
a.res_value,
a.reason,
a.test_type,
a.date_collected,
a.date_received,
k.kind_name,
sum(case when metabolite_name = "Creatinine" then t.res_val end) as Creatinine,
sum(case when metabolite_name = "Glucose" then t.res_val end) as Glucose,
sum(case when metabolite_name = "pH" then t.res_val end) as pH
FROM test_requisitions AS a
INNER JOIN personal_info AS c ON (a.user_id = c.user_id)
INNER JOIN test_types AS d ON (a.test_type = d.test_type)
INNER JOIN kinds AS k ON (k.id = d.kind_id)
INNER JOIN test_names AS n ON (d.name_id = n.id)
INNER JOIN docs AS e ON (a.doc_id = e.id)
INNER JOIN test_metabolites AS t ON (t.test_id = a.test_id)
RIGHT JOIN metabolites AS m ON (m.id = t.metabolite_id)
GROUP BY a.test_id
ORDER BY (a.date_approved IS NOT NULL),(a.res_value IS NOT NULL), a.date_req, c.last_name ASC;
Most of your joins are inner joins. The last is a right outer join. As written, the query keeps all the metabolites, but not necessarily all the tests.
I would suggest that you change them all to left outer joins, because you want to keep all the rows in the first table:
FROM test_requisitions AS a
LEFT JOIN personal_info AS c ON (a.user_id = c.user_id)
LEFT JOIN test_types AS d ON (a.test_type = d.test_type)
LEFT JOIN kinds AS k ON (k.id = d.kind_id)
LEFT JOIN test_names AS n ON (d.name_id = n.id)
LEFT JOIN docs AS e ON (a.doc_id = e.id)
LEFT JOIN test_metabolites AS t ON (t.test_id = a.test_id)
LEFT JOIN metabolites AS m ON (m.id = t.metabolite_id)
I would also suggest that your aliases be related to the table, so tr for test_requisition, pi for personal_info, and so on.

only returning records when s.id = u.summary_id

select
s.id, s.description, s.improvement, s.previous_year_id,
s.current_year_id, s.first_name, s.last_name, s.username,
s.finding, s.action, s.share, s.learned, s.timestamp,
d.title as department_title,
group_concat(g.title SEPARATOR \' | \') as strategic_goals,
y1.year as current_year_title, y2.year as previous_year_title,
u.summary_id, u.file_name as file_name
from
summary s, year y1, year y2, strategic_goal_entries sge,
goal g, department d, uploads u
where
s.id = sge.summary_id
and
s.current_year_id = y1.id
and
s.previous_year_id = y2.id
and
sge.goal_id = g.id
and
s.id = u.summary_id
and
s.department_id = d.id
and
s.department_id = '4'
group by
s.id
This only returns records from the summary table that has a relating record in the uploads table (s.id = uploads.summary_id) that contain a value within the uploads.summary_id field
I want to return all records, whether or not it has a file associated with it.
Any help is appreciated.
Suggest refactoring this SQL query to use ANSI joins. To achive your goal, you'd want a LEFT JOIN instead:
SELECT /*your columns*/
from summary s
INNER JOIN year y1 ON s.current_year_id = y1.id
INNER JOIN year y2 ON s.previous_year_id = y2.id
INNER JOIN strategic_goal_entries sge ON s.id = sge.summary_id
INNER JOIN goal g ON sge.goal_id = g.id
INNER JOIN department d ON s.department_id = d.id
LEFT JOIN uploads u ON s.id = u.summary_id
WHERE s.department_id = '4'
group by s.id