MYSQL pivoting rows and limiting by rows of a specific column - mysql

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;

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;

Mysql Pivot rows to columns

I have a table of data which some of data looks like below.
Table name Uk_Small_Stage1
name created 1m
IA UK Smaller Companies 17/10/2017 3.9
Jupiter UK Smaller Companies I Acc 17/10/2017 6.96
Old Mutual UK Smaller Companies Focus R Inc GBP 17/10/2017 2.19
TB Amati UK Smaller Companies B Acc 17/10/2017 4.85
TM Cavendish AIM B 17/10/2017 2.34
I want to pivot the table to look like
Created IA UK Smaller Companies Jupiter UK Smaller Companies I Acc Old Mutual UK Smaller Companies Focus R Inc GBP
17/10/2017 3.9 6.96 2.19
(a column should appear for each row against the field "name".
The Uk_Small_Stage1 has multiple records for each date.
I am trying to use the code below which should dynamically build and execute the pivot but am getting mysql errors.
Could any one help please?
SET group_concat_max_len=2048;
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(IF(name = ''',
name,
''', 1m, NULL)) AS ‘,
CONCAT("`”,name,"`")
)
)
) INTO #sql
FROM UK_Small_Stage1;
SET #sql = CONCAT('SELECT created, ', #sql, ' FROM UK_Small_Stage1 GROUP BY created’);
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Latest code
SET group_concat_max_len=2048;
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(IF(name = ''',
name,
''', 1m, NULL)) AS ‘,
CONCAT(''',name,''')
)
)
) INTO #sql
FROM UK_Small_Stage1;
SET #sql = CONCAT('SELECT created, ', #sql, ' FROM UK_Small_Stage1 GROUP BY created’);
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

put results of execute statement into table in MySQL

At MySQL pivot efficiency
I was wondering how to pivot a table of stock prices in MySQL. The consensus seems to be that this is not a good thing to do. I originally wanted each column to be an ID number and each row to be a date. I got much more speed by making each column a date and each row an ID number:
SET ##group_concat_max_len = 1000000;
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(IF(ddate = ',
'ddate',
',closing_price, NULL)) AS ''',
DATE_FORMAT(ddate,'%Y%m%d'),''''
)
) INTO #sql
FROM rawdatatable;
SET #sql = CONCAT('SELECT idnum , ', #sql, ' FROM rawdatatable GROUP BY idnum');
SELECT #sql;
PREPARE stmt FROM #sql;
EXECUTE stmt;
Is there any way to put the results of the EXECUTE statement into a table, where each column name is a different ddate?
Change this line
SET #sql = CONCAT('SELECT idnum , ', #sql, ' FROM rawdatatable GROUP BY idnum');
to
SET #sql = CONCAT('CREATE TABLE blah AS SELECT idnum , ', #sql, ' FROM rawdatatable GROUP BY idnum');
Try to put the result into a temp table like #Desolator say. Something like this in MySQL console
mysql>CREATE TABLE temp_result AS
SELECT * FROM rawdatatable
WHERE ...;

MySQL dynamic pivot table

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.