MySQL dynamic pivot table - mysql

Im trying to get a pivot table with dynamic columns to work. When user_id is a string, it works fine but if its an int, then it seems to fail
Here is what I have so far with the assistance of past questions:
CREATE TABLE measure2
(`inspection_date` date, `user_id` int, `score` int, comment text)
;
INSERT INTO measure2
(`inspection_date`, `user_id`, `score`, comment)
VALUES
('2012-10-16', 0, 0, null),
('2012-10-16', 1, 0, null),
('2012-10-16', 2, 0, null),
('2012-10-16', 3, 0, null),
('2012-10-17', 0, 1, null),
('2012-10-17', 1, 1, null),
('2012-10-17', 2, 1, null),
('2012-10-18', 3, 1, null)
;
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'max(case when user_id = ''',
user_id,
''' then score end) AS ',
user_id
)
) INTO #sql
FROM measure2;
SET #sql = CONCAT('SELECT inspection_date, ', #sql, '
FROM measure2
GROUP BY inspection_date');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
see: http://sqlfiddle.com/#!2/eab24/1
Im sure its something simple, but what am I missing?
Thanks

Since the values are in int you are are making them the column names, you have to wrap the values in a backtick
The sql will look like:
max(case when user_id = 1 then score end) as `1`
The full query will be:
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'max(case when user_id = ''',
user_id,
''' then score end) AS `',
user_id, '`'
)
) INTO #sql
FROM measure2;
SET #sql = CONCAT('SELECT inspection_date, ', #sql, '
FROM measure2
GROUP BY inspection_date');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
See SQL Fiddle with Demo

Simple indeed - numbers alone aren't valid column names in SQL, so you need to amend your code to enclose them in backticks:
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'max(case when user_id = ',
user_id,
' then score end) AS `',
user_id,
'`'
)
) INTO #sql
FROM measure2;
SET #sql = CONCAT('SELECT inspection_date, ', #sql, '
FROM measure2
GROUP BY inspection_date');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
I suggest retaining this change for string values as well, in case some of your string values match reserved words or include spaces.
(Also, ' aren't required around numeric values, so I have removed them from the case clauses.)
SQLFiddle here.

Related

Mysql query only showing rows affected and not the table

The following query is only returning rows affected and not the table.
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'max(case when department = ''',
department,
''' then questionValue end) ',
department
)
) INTO #sql
FROM
jos_survey_submission_values;
SET #sql = CONCAT('SELECT questionNumber AS "", category AS Category, dimension AS Dimension, subDimension AS `Sub-Dimension`, ', #sql, '
FROM jos_survey_submission_values
WHERE company_id = "180"
GROUP BY category, dimension, subDimension, questionNumber
ORDER BY questionNumber ASC');
PREPARE stmt FROM #sql;
EXECUTE stmt;
What can I do to get it to return the table?

How to print more than one values in Pivot Table?

I Have a table Attendances
and then I Make a Report using this Query
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(case when `tanggal` = ''',
`tanggal`,
''' then `in_time` end) AS `',
`tanggal`, '`'
) ORDER BY `id_employee` ASC SEPARATOR ',\n'
) INTO #sql
FROM `attendances` ;
SET #sql2 = CONCAT('SELECT id_employee, ', #sql, ' FROM attendances GROUP BY id_employee');
PREPARE stmt FROM #sql2;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Output Query :
Question : I Want To Print in_time and out_time after clause then ? Is it Possible ?
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(case when `tanggal` = ''', `tanggal`, ''' then CONCAT(in_time,''-'', out_time) end) AS `', `tanggal`, '`'
) ORDER BY `id_employee` ASC SEPARATOR ',\n'
) INTO #sql
FROM `attendances` ;
SET #sql2 = CONCAT('SELECT id_employee, ', #sql, ' FROM attendances GROUP BY id_employee');
PREPARE stmt FROM #sql2;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Generate result in CSV file using prepared statement query in laravel

I have created this query to generate report and its working fine but i want to download the result of this query in .CSV file. How to execute this query in laravel ?
Query :
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'max(case when wm.SubPointId = ''',
wm.SubPointId,
''' then Balance else 0 end) AS ',
REPLACE ( ws.SubPointType, ' ', '' )
)
) INTO #sql
FROM wallet_master wm, wallet_subpoints ws WHERE wm.SubPointId = ws.SubPointId;
SET #sql = CONCAT('SELECT MobileNo, ', #sql, ', sum(Balance) as `TotalBalance`
FROM wallet_master wm
GROUP BY MobileNo');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Unable to pass parameter value in Concat select Prepared statements

I found the stored procedure does not execute only this portion:
SET #sql
= CONCAT('SELECT TraineeID, ', #sql, '
from tbl_submit_coursefee c
where c.BatchID='BID'
group by c.TraineeID');
in where clause '' quotes do not allow and without quotes query return empty but if I put the parameter value in where clause straight then it works. I'm really stack with this.
Here is my prepared statement (working fine):
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT ('MAX(IF(BillNo = ''', BillNo, ''', CRA, NULL)) AS `Inv.', BillNo, '`')
) INTO #sql
FROM tbl_submit_coursefee
WHERE BatchID="ID-Welding/FMMTTC-01M/R8/01";
SET #sql
= CONCAT('SELECT TraineeID, ', #sql, '
from tbl_submit_coursefee c
where c.BatchID="ID-Welding/FMMTTC-01M/R8/01"
group by c.TraineeID');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
when put this statement in a stored procedure (not working):
DELIMITER ##
DROP PROCEDURE GetRetainment ##
CREATE PROCEDURE vtproject.GetRetainment
(IN `BID` VARCHAR(100))
BEGIN
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT ('MAX(IF(BillNo = '', BillNo, '', CRA, NULL)) AS `Inv.', BillNo, '`')
) INTO #sql
FROM tbl_submit_coursefee
WHERE BatchID=BID;
SET #sql
= CONCAT('SELECT TraineeID, ', #sql, '
from tbl_submit_coursefee c
where c.BatchID='BID'
group by c.TraineeID');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END ##
DELIMITER ;
If I select #sql before prepare stmt FROM #sql then output as below:
SELECT TraineeID, MAX(IF(BillNo = 1, CRA, NULL)) AS `Inv.1`,MAX(IF(BillNo = 2, CRA, NULL)) AS `Inv.2`,MAX(IF(BillNo = 3, CRA, NULL)) AS `Inv.3`,MAX(IF(BillNo = 4, CRA, NULL)) AS `Inv.4`,MAX(IF(BillNo = 5, CRA, NULL)) AS `Inv.5`,MAX(IF(BillNo = 6, CRA, NULL)) AS `Inv.6`,MAX(IF(BillNo = 7, CRA, NULL)) AS `Inv.7` from tbl_submit_coursefee c where c.BatchID=BID group by c.TraineeID
you need to escape the quotes,
like this :
SET #sql
= CONCAT('SELECT TraineeID, ', #sql, '
from tbl_submit_coursefee c
where c.BatchID=''',BID,'''
group by c.TraineeID');
according with doc : http://dev.mysql.com/doc/refman/5.7/en/string-literals.html
I found the solution in another way myself.
BEGIN
SET #sql = NULL;
SET #bid=BID;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT ('MAX(IF(BillNo = ', BillNo, ', CRA, NULL)) AS `Inv.', BillNo, '`')
) INTO #sql
FROM tbl_submit_coursefee
WHERE BatchID=#bid;
SET #sql
= CONCAT('SELECT TraineeID, ', #sql, '
from tbl_submit_coursefee c
where c.BatchID=#bid
group by c.TraineeID');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END

MYSQL pivoting rows and limiting by rows of a specific column

Not entirely sure how to word the question so I gave it my best show and am hoping that the explanation will help get the point across. Any questions, please ask.
I have the following setup for my database:
create table spooner_pec
(
id int,
year varchar(20),
policy_number int,
primary_name varchar(200),
experience_rate decimal(10,2),
mco_name varchar(200)
);
with these values being inserted:
insert into spooner_pec values
(1,'2009',183586,'ZBIN LANDSCAPING INC', 1.22, 'GENEX CARE FOR OHIO'),
(1,'2011',183586,'ZBIN LANDSCAPING INC', 0.93, 'COMPMANAGEMENT HEALTH SYSTEMS, INC.'),
(1,'2012',183586,'ZBIN LANDSCAPING INC', 0.92, 'HEALTH MANAGEMENT SOLUTIONS, INC.'),
(1,'2013',183586,'ZBIN LANDSCAPING INC', 0.50, 'CAREWORKS'),
(1,'2014',183586,'ZBIN LANDSCAPING INC', 0.47, 'UNIVERSITY HOSPITALS COMPCARE'),
(1,'2010',183586,'ZBIN LANDSCAPING INC', 1.27, 'SHEAKLEY UNICOMP')
The query that I have working so far is this:
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'max(case when year = ',
year,
' then experience_rate end) AS `',
year, '-Pen`'
) ORDER BY year
) INTO #sql
FROM
spooner_pec;
SET #sql = CONCAT('SELECT policy_number, primary_name, ', #sql, '
FROM spooner_pec
GROUP BY policy_number');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
So I have one row for each company and then a year-pen column for each year. What I need to do now is only get the rows where the penalty of the latest year is greater than 1, for example. So if the last year entered for all the data was 2014, I need where 2014-Pen, in this case, is > 1.
SQLFiddle
Do another query to get the last year, and merge that into the SQL.
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'max(case when year = ',
year,
' then experience_rate end) AS `',
year, '-Pen`'
) ORDER BY year
) INTO #sql
FROM
spooner_pec;
SELECT MAX(year) INTO #lastYear FROM spooner_pec;
SET #sql = CONCAT('SELECT policy_number, primary_name, ', #sql, '
FROM spooner_pec
GROUP BY policy_number
HAVING `', #lastYear, '-Pen` > 1');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;