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
Related
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;
I came across the query below to dynamically convert rows into columns with Mysql. Does anyone know what the the 3 single quotes do before & after the Product_Name field?
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'count(case when Product_Name = ''',
Product_Name,
''' then 1 end) AS ',
replace(Product_Name, ' ', '')
)
) INTO #sql
from products;
SET #sql = CONCAT('SELECT pt.partner_name, ', #sql, ' from partners pt
left join sales s
on pt.part_id = s.partner_id
left join products pd
on s.product_id = pd.prod_id
group by pt.partner_name');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
https://dev.mysql.com/doc/refman/5.7/en/string-literals.html says:
A ' inside a string quoted with ' may be written as ''.
There are lots of examples on that manual page.
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
In a sql database, I have this:
And I want to create another table that shows the data like this:
Which query should I use?
Possible duplicate of: MySQL pivot table query with dynamic columns. However, what you want is a "pivot" query. You can do this dynamically so you can continue to add new field names and don't have to worry about it pulling those in. Here is the sample code in that question, which would be very similar to what you're trying to do:
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(IF(pa.fieldname = ''',
fieldname,
''', pa.fieldvalue, NULL)) AS ',
fieldname
)
) INTO #sql
FROM product_additional;
SET #sql = CONCAT('SELECT p.id
, p.name
, p.description, ', #sql, '
FROM product p
LEFT JOIN product_additional AS pa
ON p.id = pa.id
GROUP BY p.id');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
And here's a great tutorial on doing this: http://buysql.com/mysql/14-how-to-automate-pivot-tables.html
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