【发布时间】:2017-08-19 14:19:44
【问题描述】:
我想根据布局不理想的表格创建报告。我可以在 excel 中创建数据透视表,但我想为基于 Web 的仪表板在线创建报告。我看过 http://datacharmer.org/downloads/pivot_tables_mysql_5.pdf 用于数据透视表,Select from table if record found in another table 用于确定值是否存在,但我无法获得所需的结果。我能够在 mysql 中创建一个带有临时表的数据透视表,但报告软件不允许数据操作。
一些答案 (qid 742) 在survey_survey_144477 表中,但其他答案在答案表中。因此,如果在survey_answers 中不存在qid,我尝试使用survey_survey_144477 中的值。
这仅适用于一份特定报告。调查结果在表survey_survey_144477 中,只有几个问题,但其他调查可能有20 或30 个问题。所以,我想让这个动态,这样我就不必更改每个报告的所有列标题。我还寻找解析列,因为survey_survey_144477 中的部分列有qid 但没有运气。我还尝试确定如何选择所有列,但忽略某些列,例如令牌、最后一页等,因为我认为如果我将其设为动态会有所帮助,但也没有运气。
如果您能提供任何帮助,我将不胜感激。
期望的输出是:
| How would you rate ... | Do you think our product ... | One a scale of 1-10 ... | Will you recommend |
+-----------------+------+------------------------------+-------------------------+--------------------+
| Excellent | Yes | 7 | Yes |
| Very good | No | 8 | Yes |
我试过了:
## Create pivot table
CREATE TEMPORARY TABLE temp
SELECT id,'144477X148X740' AS lid, 740 AS qid, 144477X148X740 AS value FROM survey_survey_144477
UNION ALL
SELECT id, '144477X148X741' AS lid, 741 AS qid, 144477X148X741 AS value FROM survey_survey_144477
UNION ALL
SELECT id, '144477X148X742SQ001' AS lid, 742 AS qid, 144477X148X742SQ001 AS value FROM survey_survey_144477
UNION ALL
SELECT id, '144477X148X745' AS lid, 745 AS qid, 144477X148X745 AS value FROM survey_survey_144477;
## Get the answers. Table survey_answers has answers from dropdowns and selection boxes.
## Other answers are in the temp table.
select T.id, SQ.question, SA.answer
from survey_questions SQ
join survey_answers SA on SA.qid = SQ.qid
join temp T on T.qid = SQ.qid
where SQ.sid = 144477
-- and exists (select SA.answer as answer
-- from survey_answers SA
-- join survey_questions SQ on SA.qid = SQ.qid
-- join temp T on T.qid = SQ.qid)
CREATE TEMPORARY TABLE temp2
select id, qid, value
from temp
where not exists (select qid from survey_answers
where temp.qid = survey_answers.qid);
describe survey_survey_144477;
+---------------------+----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+----------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| token | varchar(35) | YES | | NULL | |
| submitdate | datetime | YES | | NULL | |
| lastpage | int(11) | YES | | NULL | |
| startlanguage | varchar(20) | NO | | NULL | |
| ipaddr | text | YES | | NULL | |
| refurl | text | YES | | NULL | |
| 144477X148X740 | varchar(5) | YES | | NULL | |
| 144477X148X741 | varchar(5) | YES | | NULL | |
| 144477X148X742SQ001 | decimal(30,10) | YES | | NULL | |
| 144477X148X745 | varchar(5) | YES | | NULL | |
| 144477X148X748 | text | YES | | NULL | |
+---------------------+----------------+------+-----+---------+----------------+
describe survey_questions ;
+----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+----------------+
| qid | int(11) | NO | PRI | NULL | auto_increment |
| parent_qid | int(11) | NO | MUL | 0 | |
| sid | int(11) | NO | MUL | 0 | |
| gid | int(11) | NO | MUL | 0 | |
| type | varchar(1) | NO | MUL | T | |
| title | varchar(20) | NO | | | |
| question | mediumtext | NO | | NULL | |
| preg | mediumtext | YES | | NULL | |
| help | mediumtext | YES | | NULL | |
| other | varchar(1) | NO | | N | |
| mandatory | varchar(1) | YES | | NULL | |
| question_order | int(11) | NO | | NULL | |
| language | varchar(20) | NO | PRI | en | |
| scale_id | int(11) | NO | | 0 | |
| same_default | int(11) | NO | | 0 | |
| relevance | mediumtext | YES | | NULL | |
| modulename | varchar(255) | YES | | NULL | |
+----------------+--------------+------+-----+---------+----------------+
describe survey_answers ;
+------------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------+-------------+------+-----+---------+-------+
| qid | int(11) | NO | PRI | 0 | |
| code | varchar(5) | NO | PRI | | |
| answer | mediumtext | NO | | NULL | |
| sortorder | int(11) | NO | MUL | NULL | |
| assessment_value | int(11) | NO | | 0 | |
| language | varchar(20) | NO | PRI | en | |
| scale_id | int(11) | NO | PRI | 0 | |
+------------------+-------------+------+-----+---------+-------+
select id, 144477X148X740, 144477X148X741, 144477X148X742SQ001, 144477X148X745, 144477X148X748 from survey_survey_144477 limit 10;
+----+----------------+----------------+---------------------+----------------+----------------+
| id | 144477X148X740 | 144477X148X741 | 144477X148X742SQ001 | 144477X148X745 | 144477X148X748 |
+----+----------------+----------------+---------------------+----------------+----------------+
| 1 | 1 | A2 | 5.0000000000 | A2 | name@email.com |
| 2 | 1 | A2 | 5.0000000000 | A2 | name@email.com |
| 3 | 1 | A2 | 5.0000000000 | A2 | name@email.com |
| 4 | 1 | A2 | 5.0000000000 | A2 | name@email.com |
| 5 | 1 | A2 | 5.0000000000 | A2 | name@email.com |
| 6 | 1 | A2 | 5.0000000000 | A2 | name@email.com |
| 7 | 1 | A2 | 5.0000000000 | A2 | name@email.com |
| 8 | 1 | A2 | 5.0000000000 | A2 | name@email.com |
| 9 | 1 | A2 | 5.0000000000 | A2 | name@email.com |
| 10 | 1 | A2 | 5.0000000000 | A2 | name@email.com |
+----+----------------+----------------+---------------------+----------------+----------------+
select qid, sid, question from survey_questions where sid = 144477;
+-----+--------+-------------------------------------------------------------------------------------------+
| qid | sid | question |
+-----+--------+-------------------------------------------------------------------------------------------+
| 748 | 144477 | Please enter your email address or phone number if you would like someone to contact you. |
| 740 | 144477 | How would you rate our product's quality? |
| 741 | 144477 | Do you think our product helps your business? |
| 742 | 144477 | One a scale of 1-10, how would you rate the value of our product? |
| 743 | 144477 | |
| 745 | 144477 | Will you recommend our product? |
+-----+--------+-------------------------------------------------------------------------------------------+
select * from survey_answers where qid between 740 and 745;
+-----+------+-----------+-----------+------------------+----------+----------+
| qid | code | answer | sortorder | assessment_value | language | scale_id |
+-----+------+-----------+-----------+------------------+----------+----------+
| 740 | 1 | Excellent | 1 | 1 | en | 0 |
| 740 | 2 | Very good | 2 | 1 | en | 0 |
| 740 | 3 | Good | 3 | 1 | en | 0 |
| 740 | 4 | Fair | 4 | 1 | en | 0 |
| 740 | 5 | Poor | 5 | 1 | en | 0 |
| 741 | A1 | Yes | 1 | 0 | en | 0 |
| 741 | A2 | No | 2 | 0 | en | 0 |
| 745 | A1 | Yes | 1 | 0 | en | 0 |
| 745 | A2 | No | 2 | 0 | en | 0 |
+-----+------+-----------+-----------+------------------+----------+----------+
更新:
我创建了一个表来将值从一个表映射到另一个表。自动化这将是一个挑战,我稍后会提到。
CREATE TABLE `survey_answers_lookup` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`sid` int(11) NOT NULL DEFAULT '0',
`qid` int(11) NOT NULL DEFAULT '0',
`survey_table_row_id` int(11) NOT NULL DEFAULT '0' COMMENT 'id that is in the survey_<id> table',
`answer` mediumtext COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO survey_answers_lookup (sid,qid,survey_table_row_id,answer)
VALUES (144477,740,1,1);
INSERT INTO survey_answers_lookup (sid,qid,survey_table_row_id,answer)
VALUES (144477,741,1,'A1');
INSERT INTO survey_answers_lookup (sid,qid,survey_table_row_id,answer)
VALUES (144477,742,1,'5.0000000000');
INSERT INTO survey_answers_lookup (sid,qid,survey_table_row_id,answer)
VALUES (144477,745,1,'A1');
INSERT INTO survey_answers_lookup (sid,qid,survey_table_row_id,answer)
VALUES (144477,748,1,'1@email.com');
INSERT INTO survey_answers_lookup(sid,qid,survey_table_row_id,answer)
VALUES (144477,740,2,'2');
INSERT INTO survey_answers_lookup (sid,qid,survey_table_row_id,answer)
VALUES (144477,741,2,'A2');
INSERT INTO survey_answers_lookup (sid,qid,survey_table_row_id,answer)
VALUES (144477,742,2,'8.0000000000');
INSERT INTO survey_answers_lookup(sid,qid,survey_table_row_id,answer)
VALUES (144477,745,2,'A2');
INSERT INTO survey_answers_lookup(sid,qid,survey_table_row_id,answer)
VALUES (144477,748,2,'2@email.com');
INSERT INTO survey_answers_lookup (sid,qid,survey_table_row_id,answer)
VALUES (144477,740,3,'5');
INSERT INTO survey_answers_lookup (sid,qid,survey_table_row_id,answer)
VALUES (144477,741,3,'A2');
INSERT INTO survey_answers_lookup (sid,qid,survey_table_row_id,answer)
VALUES (144477,742,3,'10.0000000000');
INSERT INTO survey_answers_lookup (sid,qid,survey_table_row_id,answer)
VALUES (144477,745,3,'A2');
INSERT INTO survey_answers_lookup(sid,qid,survey_table_row_id,answer)
VALUES (144477,748,3,'3@email.com');
结果
select * from survey_answers_lookup;
# id, sid, qid, survey_table_row_id, answer
'1', '144477', '740', '1', '1'
'2', '144477', '741', '1', 'A1'
'3', '144477', '742', '1', '5.0000000000'
'4', '144477', '745', '1', 'A1'
'5', '144477', '748', '1', '1@email.com'
'6', '144477', '740', '2', '2'
'7', '144477', '741', '2', 'A2'
'8', '144477', '742', '2', '8.0000000000'
'9', '144477', '745', '2', 'A2'
'10', '144477', '748', '2', '2@email.com'
'11', '144477', '740', '3', '5'
'12', '144477', '741', '3', 'A2'
'13', '144477', '742', '3', '10.0000000000'
'14', '144477', '745', '3', 'A2'
'15', '144477', '748', '3', '3@email.com'
尝试获取问题和答案。
-- Gives all of the rows from the answers_table even if that is not in the
-- survey_answers_lookup table because of the left join. 740 should only be printed three times.
select
--SQ.qid,
SA.code,
SQ.question,
SQ.type,
-- Types can be: ! * 1 E F K L M N Q R S T X Y
if (SQ.type IN ('B','M','L'), SA.answer, LU2.answer) as 'answer'
from survey_questions SQ
left join survey_answers SA on SA.qid = SQ.qid
-- and SQ.type IN ('B','M','L')
left join survey_answers_lookup LU on LU.qid = SQ.qid
and LU.answer = SA.code
-- and SQ.type IN ('B','M','L')
left join survey_answers_lookup LU2 on LU2.qid = SQ.qid
and SQ.title = 'Q7'
where SQ.sid = 144477;
# --SQ.qid, code, question, type, answer
'740', '1', 'How would you rate our product\'s quality?', 'L', 'Excellent'
'740', '2', 'How would you rate our product\'s quality?', 'L', 'Very good'
'740', '5', 'How would you rate our product\'s quality?', 'L', 'Poor'
'740', '3', 'How would you rate our product\'s quality?', 'L', 'Good'
'740', '4', 'How would you rate our product\'s quality?', 'L', 'Fair'
'741', 'A1', 'Do you think our product helps your business?', 'L', 'Yes'
'741', 'A2', 'Do you think our product helps your business?', 'L', 'No'
'741', 'A2', 'Do you think our product helps your business?', 'L', 'No'
'742', NULL, 'One a scale of 1-10, how would you rate the value of our product?', 'K', NULL
'745', 'A1', 'Will you recommend our product?', 'L', 'Yes'
'745', 'A2', 'Will you recommend our product?', 'L', 'No'
'745', 'A2', 'Will you recommend our product?', 'L', 'No'
'748', NULL, 'Please enter your email address or phone number if you would like someone to contact you.', 'S', '1@email.com'
'748', NULL, 'Please enter your email address or phone number if you would like someone to contact you.', 'S', '2@email.com'
'748', NULL, 'Please enter your email address or phone number if you would like someone to contact you.', 'S', '3@email.com'
-- 返回多于一行
select
SQ.qid,
SQ.question,
SQ.type,
-- Types can be: ! * 1 E F K L M N Q R S T X Y
if (SQ.type IN ('B','M','L'),
(select SA.answer
from survey_answers SA
join survey_questions SQ2 on SQ2.qid = SA.qid
join survey_answers_lookup LU on LU.qid = SQ2.qid
and LU.answer = SA.code),
(select LU2.answer
from survey_answers_lookup LU2
join survey_questions SQ3 on SQ3.qid = LU2.qid)
) as answer
from survey_questions SQ
where SQ.sid = 144477;
如果类型为“B”、“M”、“L”,则此方法有效。
select
-- qid,
-- SA.code,
question,
-- Types can be: ! * 1 E F K L M N Q R S T X Y
if (type IN ('B','M','L'),
(select answer
from survey_answers
where survey_questions.qid = survey_answers.qid
and survey_answers_lookup.qid = survey_questions.qid
and survey_answers_lookup.answer = survey_answers.code
),
(0 -- select answer
-- from survey_answers_lookup
-- where survey_questions.qid = survey_answers_lookup.qid
)
) as answer
from survey_questions
join survey_answers_lookup on survey_answers_lookup.qid = survey_questions.qid
where survey_questions.sid = 144477;
'Do you think our product helps your business?', 'Yes'
'Do you think our product helps your business?', 'No'
'Do you think our product helps your business?', 'No'
'How would you rate our product\'s quality?', 'Excellent'
'How would you rate our product\'s quality?', 'Very good'
'How would you rate our product\'s quality?', 'Poor'
'One a scale of 1-10, how would you rate the value of our product?', '0'
'One a scale of 1-10, how would you rate the value of our product?', '0'
'One a scale of 1-10, how would you rate the value of our product?', '0'
'Please enter your email address or phone number if you would like someone to contact you.', '0'
'Please enter your email address or phone number if you would like someone to contact you.', '0'
'Please enter your email address or phone number if you would like someone to contact you.', '0'
'Will you recommend our product?', 'Yes'
'Will you recommend our product?', 'No'
'Will you recommend our product?', 'No'
-- 错误:子查询返回多行。
select
-- qid,
-- SA.code,
question,
-- Types can be: ! * 1 E F K L M N Q R S T X Y
if (type IN ('B','M','L'),
(select answer
from survey_answers
where survey_questions.qid = survey_answers.qid
and survey_answers_lookup.qid = survey_questions.qid
and survey_answers_lookup.answer = survey_answers.code
),
(select answer
from survey_answers_lookup
join survey_questions on survey_questions.qid = survey_answers_lookup.qid
where not exists (select * -- if the value is not in survey_answers table (not exists)
from survey_answers
where survey_answers.qid = survey_answers_lookup.qid
LIMIT 1
)
)
) as answer
from survey_questions
join survey_answers_lookup on survey_answers_lookup.qid = survey_questions.qid
where survey_questions.sid = 144477;
-- ----------------
-- ----------------
select
-- survey_answers_lookup.survey_table_row_id,
-- qid,
-- SA.code,
question,
-- Types can be: ! * 1 E F K L M N Q R S T X Y
if (type IN ('B','M','L'),
(select answer
from survey_answers
where survey_questions.qid = survey_answers.qid
and survey_answers_lookup.qid = survey_questions.qid
and survey_answers_lookup.answer = survey_answers.code
),
(select answer
from survey_answers_lookup
where qid not in (select qid
from survey_answers
)
)
) as answer
from survey_questions
join survey_answers_lookup on survey_answers_lookup.qid = survey_questions.qid
where survey_questions.sid = 144477;
这个想法是如果类型是“B”、“M”、“L”,则从表survey_answers 中获取答案,如果它们是另一种类型,则从表survey_answers_lookup 中获取答案。如果答案不在该表中,则 qid 不在表survey_answers 中。表survey_answers_lookup 有qid 的742 和748 的三个答案,查询不知道要获取哪个值。我想我需要添加另一个值来加入它。谢谢
select answer, qid
from survey_answers_lookup
where qid not in (select qid from survey_answers)
# answer, qid
'5.0000000000', '742'
'1@email.com', '748'
'8.0000000000', '742'
'2@email.com', '748'
'10.0000000000', '742'
'3@email.com', '748'
这可能很乱,但也许我可以添加一个计数器,然后将计数器与表survey_answers_lookup 中的 id 进行比较?
select answer
from survey_answers_lookup
where qid not in (select qid from survey_answers)
and id = @counter
我想我已经成功了。
set @counter = 0;
select
@counter := @counter+1 AS newindex,
survey_answers_lookup.id as id,
survey_answers_lookup.survey_table_row_id,
survey_answers_lookup.qid,
question,
-- Types can be: ! * 1 E F K L M N Q R S T X Y
if (type IN ('B','M','L'),
(select answer
from survey_answers
where survey_questions.qid = survey_answers.qid
and survey_answers_lookup.qid = survey_questions.qid
and survey_answers_lookup.answer = survey_answers.code
),
(select answer
from survey_answers_lookup
where qid not in (select qid from survey_answers)
and id = @counter
)
) as answer
from survey_questions
join survey_answers_lookup on survey_answers_lookup.qid = survey_questions.qid
where survey_questions.sid = 144477
order by survey_answers_lookup.id;
# newindex, id, survey_table_row_id, qid, question, answer
'1', '1', '1', '740', 'How would you rate our product\'s quality?', 'Excellent'
'2', '2', '1', '741', 'Do you think our product helps your business?', 'Yes'
'3', '3', '1', '742', 'One a scale of 1-10, how would you rate the value of our product?', '5.0000000000'
'4', '4', '1', '745', 'Will you recommend our product?', 'Yes'
'5', '5', '1', '748', 'Please enter your email address or phone number if you would like someone to contact you.', '1@email.com'
'6', '6', '2', '740', 'How would you rate our product\'s quality?', 'Very good'
'7', '7', '2', '741', 'Do you think our product helps your business?', 'No'
'8', '8', '2', '742', 'One a scale of 1-10, how would you rate the value of our product?', '8.0000000000'
'9', '9', '2', '745', 'Will you recommend our product?', 'No'
'10', '10', '2', '748', 'Please enter your email address or phone number if you would like someone to contact you.', '2@email.com'
'11', '11', '3', '740', 'How would you rate our product\'s quality?', 'Poor'
'12', '12', '3', '741', 'Do you think our product helps your business?', 'No'
'13', '13', '3', '742', 'One a scale of 1-10, how would you rate the value of our product?', '10.0000000000'
'14', '14', '3', '745', 'Will you recommend our product?', 'No'
'15', '15', '3', '748', 'Please enter your email address or phone number if you would like someone to contact you.', '3@email.com'
现在我需要创建一个触发器,以便在创建新调查并回答问题时更新此表。
(来自 cmets)
SELECT *
FROM survey_survey_144477
UNION ALL
SELECT id,
144477X148X741,
741 AS qid,
144477X148X741 AS value
FROM survey_survey_144477
UNION ALL
SELECT id,
144477X148X742SQ001,
742 AS qid,
144477X148X742SQ001 AS value
FROM survey_survey_144477
UNION ALL
SELECT id,
144477X148X745, 745 AS qid,
144477X148X745 AS value
FROM survey_survey_144477;
select T.id, SQ.question, SQ.type, -- SA.answer,
case SQ.type
when 'L' then SA.answer -- list choice --
when 'M' then -- multiple choice --
when 'B' then -- array-10(B)
when 'T' OR 'N' then T.value -- text or numeric
when 'K' then T.value -- slider --
else "Do nothing" end as 'answer'
from survey_questions SQ
join survey_answers SA ON SA.qid = SQ.qid
join temp T ON T.qid = SQ.qid and T.value = SA.code
where SQ.sid = 144477 --
and SQ.type = 'K'
order by T.id;
【问题讨论】:
-
您在寻找
LEFT JOIN吗? -
谢谢 Rick,我尝试了左连接。我会发布代码,但在此线程上看不到回复选项。我只看到一个评论选项。我在这个链接上尝试了代码,但经过一段时间的调试后我无法让它工作。 olihb.com/2010/07/31/using-crystal-reports-with-limesurvey 我正在尝试从该代码创建存储过程,但出现排序错误。所以我将数据库更新为 utf8mb4 ,但我仍然卡住了。这个想法是对数据进行格式化,这样我就可以在不使用 excel 创建数据透视表的情况下创建报告。
-
(当您获得更多声誉时,您可以添加 cmets、答案和编辑您的问题。)
-
我从我找到的python代码中得到了一个想法。数据库将 question-id 附加到列名称的调查 ID 中。代码从模式中获取列,然后遍历每一行,然后遍历表。然后我需要在另一个表中查找 ID。如果 ID 是特定 ID,我需要从另一个表中获取答案。我可以用编程语言做到这一点,但我还不确定如何在 MySQL 中做到这一点。我现在要阅读有关循环和游标的内容。
-
我很惭愧地承认我已经尝试了多少天来完成这项工作。该软件为每个调查创建一个新表。每个问题都有自己的专栏。所以,我永远不知道有多少列将添加到表中。我能够通过一项包含 3 个我想要的问题的调查来做到这一点:(我希望我能更好地格式化这个)
标签: mysql pivot-table mariadb exists