mysql - 具有许多表的复杂查询,这可以在一个查询中实现吗?

标签 mysql sql

我在以下数据库设计中遇到了麻烦(为示例进行了简化)。它允许人们创建自定义表单,与 google spreadsheat 表单非常相似。表单生成脚本已完成,包括将答案保存到数据库中。我在显示用户输入时遇到问题。

表格表格(每个表格是表格中的一行)

form_id | form_name
1         Contact Form
2         BBQ sign up Form

Table questions(表格中的问题)

question_id | form_id | question_name      | sorting_order
1             1         Full Name            1
2             1         E-mail address       2
3             1         Subject              3
4             1         Message              4
5             2         Your name            1
6             2         Are you vegetarian?  2
7             2         Beer or wine?        3    

表格completed_forms(将答案组合在一起)

complete_id | form_id | timestamp
1            1          1339496914
2            1          1148691493
3            2          1256235334

表格answers(用户对特定问题的回答)

answer_id | complete_id | question_id | answer
1           1             1             Barack Obama
2           1             2             president@whitehouse.gov
3           1             3             Test message
4           1             4             This is a test. Regards, Barack.
5           2             1             Thomas something
6           2             2             thomas@email.com
7           2             3             Another message
8           2             4             Hey, it's Thomas. This is my message.
9           3             5             Dirk
10          3             6             No, I love meat
11          3             7             Red wine!

我想显示的是用户输入的概览,这非常复杂,因为每个表单的名称和列数不同。例如,我想显示来自联系表单 (form_id: 1) 的用户输入,如下所示:

id | timestamp | Full Name | E-mail Address | Subject | Message
1    133949...   Barack...   president@w...   Test...   This is a t...
2    114869...   Thomas...   thomas@emai...   Anot...   Hey, it's T...

从 form_id 2 如下:

id | timestamp | Your name | Are you vegetarian? | Beer or Wine?
3    125623...   Dirk        No, I love meat       Red wine!

有人知道我是否以及如何实现这一目标吗?

非常感谢任何愿意花时间解决这个问题的人!

最佳答案

基本上您正在尝试编写一个 PIVOT,但 MySQL 本身没有 PIVOT 函数,因此您将不得不编写一些不同的查询。对于此查询的静态版本,您可以在其中编码问题的值,您可以使用以下内容:

表格 1(参见 SQL Fiddle with Demo):

select cf.complete_id
  , cf.ts
  , Min(CASE WHEN q.question_name = 'Full Name' THEN a.answer END) as 'Full Name'
  , Min(CASE WHEN q.question_name = 'Email Address' THEN a.answer END) as 'Email Address'
  , Min(CASE WHEN q.question_name = 'Subject' THEN a.answer END) as 'Subject'
  , Min(CASE WHEN q.question_name = 'Message' THEN a.answer END) as 'Message'
from completed_forms cf
inner join questions q
  on cf.form_id = q.form_id
inner join answers a
  on cf.complete_id = a.complete_id
  and q.question_id = a.question_id
where cf.form_id = 1
group by cf.complete_id

表格 2(参见 SQL Fiddle with Demo):

select cf.complete_id
  , cf.ts
  , Min(CASE WHEN q.question_name = 'Your Name' THEN a.answer END) as 'Your Name'
  , Min(CASE WHEN q.question_name = 'Are you vegetarian?' THEN a.answer END) as 'Are you vegetarian?'
  , Min(CASE WHEN q.question_name = 'Beer or Wine' THEN a.answer END) as 'Beer or Wine'
from completed_forms cf
inner join questions q
  on cf.form_id = q.form_id
inner join answers a
  on cf.complete_id = a.complete_id
  and q.question_id = a.question_id
where cf.form_id = 2
group by cf.complete_id

现在,由于您的问题将针对每种形式发生变化,因此您应该考虑自动化 Pivot。我建议查看位于此处的文章:

http://www.artfulsoftware.com/infotree/queries.php#523

它包含如何在 MySql 中使用数据透视表的示例。 StackOverflow 上还有其他答案应该能够帮助动态编写此内容:

mysql query to dynamically convert row data to columns

MySQL pivot table with dynamic headers based on single column data

关于mysql - 具有许多表的复杂查询,这可以在一个查询中实现吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10994902/

相关文章:

sql - 有什么办法可以清理这个复杂的聚合函数吗?

php - 这种登录方式安全吗

python - 为什么我无法在Python中获取sql语句?

php - Codeigniter 中的嵌套连接

php - 如何在 UPDATE 语句中使用 SELECT 中的值?

sql - 在postgres中展平嵌套记录

mysql结果格式为单行

mysql - 从其他表中加入最大值的最佳和最佳方式

SQL - 使用 Postgres 中的附加查询扩展 INSERT 查询的结果

mysql - 如何计算数据库中具有特定值的列数(查询)