Convert rows into columns in MySQL Query - mysql

I am getting above result from this query
SELECT sa.Student_Id,
CONCAT_WS(' ', es.Student_FName, es.Student_LName) AS Full_Name,
sa.Attendance_Date ,
sa.Attendance_Status
FROM student_attendance sa
INNER JOIN courses c
ON c.Course_Id = sa.Course_Id
INNER JOIN campus ca
ON ca.Campus_Id = c.Campus_Id
INNER JOIN students es
ON es.Student_Id = sa.Student_Id
WHERE sa.Course_Id = 1
ORDER BY sa.Attendance_Date DESC;
but i want this result
Can someone Do this for me Please..

select max(student|_id),full_name as student_FName ,
case attendance_date when attendance_date ='03-02-2016' and attendance_status =0
and full_name ='Shehriar Khan'
Then 'p' end as '3/1/2016',
case attendance_status when attendance_date ='03-01-2016'
and attendance_status =0 and full_name ='Ahtesham Illahi'
Then 'p' end as '3/2/2016'
from table_name
group_by full_name,attendance_date,attendance_stauts

Try like this
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(IF(a.attendance_status = ''',
attendance_status,
''', IF(a.attendance_status = "1","P","X"), NULL)) AS "',
attendance_date,'"'
)
) INTO #sql
FROM student_attendance;
SET #sql = CONCAT('SELECT a.Student_ID,a.student_name,', #sql, '
FROM student_attendance a
LEFT JOIN student_attendance AS b
ON a.Student_ID=b.Student_ID GROUP BY a.Student_ID,b.Student_ID');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Fiddle link

Related

Dynamic table headers in Laravel Blade from MySQL pivot table

I have a dynamic MySQL query and I want to create a table based on the dynamic MySQL pivot table. I am using Laravel, and I have the query in a blade file instead of a controller. Below is the query.
How can I create a dynamic table, with dynamic headers (instead of static) ?
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(IF(assessements.id = ''',
assessements.id,
''', marks.mark, NULL)) AS ',
replace(assessement_name, ' ', '')
)
) INTO #sql
from assessements INNER JOIN marks ON marks.assessement_id=assessements.id WHERE assessements.term_id=2;
SET #sql = CONCAT('SELECT student_subject_averages.student_average,
student_subject_averages.ca_average,
student_subject_averages.exam_mark,
subjects.subject_name,
subjects.subject_type,
subjects.id as subject_id,
users.name,
users.salutation,
users.lastname, ', #sql, ' from marks
INNER JOIN assessements ON assessements.id = marks.assessement_id
INNER JOIN teaching_loads ON teaching_loads.id = marks.teaching_load_id
INNER JOIN subjects ON subjects.id = teaching_loads.subject_id
INNER JOIN users ON users.id = marks.teacher_id
INNER JOIN student_subject_averages ON student_subject_averages.student_id = marks.student_id
WHERE marks.student_id = 1869 AND `assessements`.`term_id` = 2 AND marks.active=1 AND student_subject_averages.teaching_load_id=marks.teaching_load_id
GROUP BY
marks.student_id,student_subject_averages.student_id,
subjects.id');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

MySQL Dynamic Pivot Table not giving proper results

I'm somewhat of a SQL rookie but I'm trying to write a pivot between three tables. I have the below query and it works perfectly aside from the MAX call. It causes my values that are less than the default value to be overridden. I have screenshots of my tables below. Any ideas on how to fix this?
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(IF(cc.company_config_key_id = ', cck.id, ', cc.config_value, \'', cck.default, '\')) AS ', cck.company_config_key
)
) INTO #sql
FROM company_config cc
LEFT JOIN company_config_key cck
ON cck.id = cc.company_config_key_id;
SET #sql = CONCAT('SELECT co.id, co.name, ', #sql, ' FROM companies co LEFT JOIN company_config cc ON cc.company_id = co.id GROUP BY co.id');
PREPARE stmt FROM #sql;
EXECUTE stmt;
companies:
company_config_key:
company_config:
Result (the secondary colors for companies 1 and 2 should be set):
It turns out I just had to set the internal if statement to NULL and then wrapped the max statement in an IFNULL.
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT('IFNULL(MAX(IF(cc.company_config_key_id = ', cck.id, ', cc.config_value, NULL)), \'', cck.default, '\') AS ',cck.company_config_key)
) INTO #sql
FROM company_config cc
LEFT JOIN company_config_key cck
ON cck.id = cc.company_config_key_id;
SET #sql = CONCAT('SELECT co.id, co.name, ', #sql, ' FROM companies co LEFT JOIN company_config cc ON cc.company_id = co.id GROUP BY co.id');
SELECT #sql;
PREPARE stmt FROM #sql;
EXECUTE stmt;

What is wrong in Mysql select query with mysql variable concatenated with string?

I have bellow query but has problem
set #lang = "en";
SELECT
COUNT(*) AS total_of_user,
COUNT(*) AS "total_of_user_#lang",
src.district AS district_name,
src.district AS "district_name_#lang"
FROM users LEFT JOIN (
SELECT
d.district_code,
d.name_en AS district,
p.name_en AS province_name,
p.`province_code`
FROM
provinces AS p LEFT JOIN districts AS d ON p.province_code = d.province_code
WHERE
p.province_code = '01'
) AS src ON src.district_code = users.district_code
WHERE
users.district_code IS NOT NULL AND
users.district_code <> '' AND
users.province_code = '01'
GROUP BY users.district_code
If I remove " from query the never run, but above query run and result came as district_name_#lang but I need the column name to be as district_name_en.
For any help thanks.
You would need to use dynamic SQL for this:
set #lang = 'en';
set #sql = '
SELECT COUNT(*) AS total_of_user,
COUNT(*) AS total_of_user_#lang,
src.district AS district_name,
src.district AS district_name_#lang
FROM users LEFT JOIN
(SELECT d.district_code, d.name_en AS district, p.name_en AS province_name, p.`province_code`
FROM provinces p LEFT JOIN
districts d
ON p.province_code = d.province_code
WHERE p.province_code = ''01''
) src
ON src.district_code = users.district_code
WHERE users.district_code IS NOT NULL AND
users.district_code <> '''' AND
users.province_code = ''01''
GROUP BY users.district_code';
set #sql = replace(#sql, '#en', #en);
prepare stmt from #sql;
execute stmt;
deallocate prepare stmt;
Note: you cannot use parameters for column names or table names in a dynamic query.

MySQL Multiple Query > storing rows into columns

I need to create a SQL query that lists the following tables. Lines from the language list as column names. Thanks
Picture table and query:
If languages are known upfront
SELECT r.id, r.parent,
MAX(CASE WHEN n.language_id = 1 THEN n.name END) cs,
MAX(CASE WHEN n.language_id = 2 THEN n.name END) en
FROM cat_route r LEFT JOIN cat_route_name n
ON r.id = n.cat_route_id
GROUP BY r.id
Here is SQLFiddle demo
If you want it to be dynamic depending on what languages you defined in language
SET #sql = NULL;
SELECT GROUP_CONCAT(CONCAT(
'MAX(CASE WHEN n.language_id = ', id, ' THEN n.name END) `', short, '`'))
INTO #sql
FROM language;
SET #sql = CONCAT(
'SELECT r.id, r.parent, ', #sql, '
FROM cat_route r LEFT JOIN cat_route_name n
ON r.id = n.cat_route_id
GROUP BY r.id');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Here is SQLFiddle demo

Pivot Table Using MySQL and Group Conact

This is a Question related to my original question
Pivot Table Using MySQL
Data in the tables are saved like this now
I have two tables Triples and Tags
Triples Table has the following Columns
id PostID TagID Value
1 1 1 Murder
2 1 1 Theft
3 2 2 Knife
4 2 2 Gun
Tags Table has the following Columns
id TagName
1 Incident
2 Weapon
I am trying to write sql to create a Pivot Table with Dynamic Headers
Output should be like this
PostID Incident Weapon
1 Murder,Theft
2 Knifie,Gun
I written a inefficient and partial sql query for this, Any help in writing this sql appreciated
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'max(CASE WHEN TagName = ''',
TagName,
''' THEN p.value END) AS `',
TagName, '`'
)
) INTO #sql
FROM tags;
SET #sql
= CONCAT('CREATE VIEW PostTags as SELECT p.postid, p.id, ', #sql, '
from triples p
left join tags t
on p.tagid = t.id
group by p.postid, p.id');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
You will have to build two strings, one for the inner rotation to create the columns of Incident and Weapon, and the second string with use GROUP_CONCAT for the outer query:
SET #sql = NULL;
SET #sql2 = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'group_concat(',
TagName,
' separator '', '') as `',
TagName, '`'
)
)
INTO #sql2
FROM tags;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'max(CASE WHEN TagName = ''',
TagName,
''' THEN p.value END) AS `',
TagName, '`'
)
)
INTO #sql
FROM tags;
SET #sql = CONCAT('select postid, ', #sql2, '
from
(
SELECT p.postid, p.id, ', #sql, '
from triples p
left join tags t
on p.tagid = t.id
group by p.postid, p.id
) d
group by postid');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
See SQL Fiddle with Demo
This is creating the SQL code:
select postId,
group_concat(incident separator ', ') incident,
group_concat(Weapon separator ', ') Weapon
from
(
SELECT p.postid, p.id,
max(CASE WHEN TagName = 'Incident' THEN p.value END) AS `Incident`,
max(CASE WHEN TagName = 'Weapon' THEN p.value END) AS `Weapon`
from triples p
left join tags t
on p.tagid = t.id
group by p.postid, p.id
) d
group by postId;
See SQL Fiddle with Demo