MySQL 按照另一个表中的字段进入的顺序对子查询进行排序

问题描述 投票:0回答:1

我有一个自定义表单生成器,管理员可以在其中单独创建字段和表单,以便这些字段可以在多个表单上重复使用。管理员可以随时对字段重新排序,并添加新字段或删除现有字段,即使在提交后也是如此。我为此有 5 个表:

forms
fields
form_fields
链接表、
submissions
submission_fields
表,它既是链接表,也包含提交字段的值。

如果字段的位置已移动,则问题在于现有提交的数据排序。在此 SQLFiddle 中,我模拟了表单的提交,其中字段的顺序为数字(1(名字)、2(姓氏)、3(电子邮件地址)、4(地址)、5(城市) 、6(州)、7(邮政编码)和 8(电话)),但随后电话号码字段 (#8) 在

email address
字段下向上移动,将顺序更改为 1、2、3、8, 4、5、6、7。

-- INIT database
CREATE TABLE forms (
  id INT AUTO_INCREMENT KEY,
  title VARCHAR(200)
);

CREATE TABLE fields (
  id INT AUTO_INCREMENT KEY,
  label VARCHAR(200)
);

CREATE TABLE form_fields (
  id INT AUTO_INCREMENT KEY,
  form_id INT,
  field_id INT
);

CREATE TABLE submissions (
  id INT AUTO_INCREMENT KEY,
  form_id INT
);

CREATE TABLE submission_fields (
  id INT AUTO_INCREMENT KEY,
  submission_id INT,
  field_id INT,
  field_value VARCHAR(255)
);

INSERT INTO forms(title) VALUES ('Form 1');

INSERT INTO fields(label) VALUES ('First Name');
INSERT INTO fields(label) VALUES ('Last Name');
INSERT INTO fields(label) VALUES ('Email Address');
INSERT INTO fields(label) VALUES ('Address');
INSERT INTO fields(label) VALUES ('City');
INSERT INTO fields(label) VALUES ('State');
INSERT INTO fields(label) VALUES ('Zip');
INSERT INTO fields(label) VALUES ('Phone');

INSERT INTO form_fields(form_id, field_id) VALUES (1, 1);
INSERT INTO form_fields(form_id, field_id) VALUES (1, 2);
INSERT INTO form_fields(form_id, field_id) VALUES (1, 3);
INSERT INTO form_fields(form_id, field_id) VALUES (1, 8);
INSERT INTO form_fields(form_id, field_id) VALUES (1, 4);
INSERT INTO form_fields(form_id, field_id) VALUES (1, 5);
INSERT INTO form_fields(form_id, field_id) VALUES (1, 6);
INSERT INTO form_fields(form_id, field_id) VALUES (1, 7);

INSERT INTO submissions(form_id) VALUES (1);

INSERT INTO submission_fields(submission_id, field_id, field_value) VALUES (1, 1, 'Joe');
INSERT INTO submission_fields(submission_id, field_id, field_value) VALUES (1, 2, 'Smith');
INSERT INTO submission_fields(submission_id, field_id, field_value) VALUES (1, 3, '[email protected]');
INSERT INTO submission_fields(submission_id, field_id, field_value) VALUES (1, 4, '123 Main St');
INSERT INTO submission_fields(submission_id, field_id, field_value) VALUES (1, 5, 'Somewhere');
INSERT INTO submission_fields(submission_id, field_id, field_value) VALUES (1, 6, 'CA');
INSERT INTO submission_fields(submission_id, field_id, field_value) VALUES (1, 7, '90210');
INSERT INTO submission_fields(submission_id, field_id, field_value) VALUES (1, 8, '555-555-5555');

-- QUERY database
SELECT
    submissions.id AS submission_id,
    submissions.form_id AS form_id,
    forms.title AS form_title,
    GROUP_CONCAT(COALESCE(form_fields.field_id, '') SEPARATOR '|') AS field_ids,
    GROUP_CONCAT(COALESCE(fields.label, '') SEPARATOR '|') AS field_labels,
    (
      SELECT
        GROUP_CONCAT(COALESCE(submission_fields.field_value, '') SEPARATOR '|')
      FROM
        submission_fields
      WHERE
        submission_fields.submission_id = submissions.id
    ) AS field_values
FROM
    submissions
LEFT OUTER JOIN
    forms
ON
    forms.id = submissions.form_id
LEFT OUTER JOIN
    form_fields
ON
    form_fields.form_id = submissions.form_id
LEFT OUTER JOIN
    fields
ON
    fields.id = form_fields.field_id
WHERE
    submissions.id = 1
GROUP BY
    submissions.id;

在主查询中,一切都正确返回。然而,在

field_ids
field_values
的子查询中,它们按原始顺序返回。因此,我需要将它们设置为与主查询中返回的顺序相同的顺序(
field_values
应该将电话号码放在第 4 个位置,因为它是字段 ID 8,并出现在
field_ids
中的第 4 个位置)。

sql mysql mariadb
1个回答
0
投票

您可以在

ORDER BY form_fields.id ASC
内添加
GROUP_CONCAT
,以根据参考文献的顺序更改结果的顺序 (
form_fields.id
)。

这是修改后的查询,其中包含您需要的结果:SQLFiddle

请注意,我还删除了子查询并加入

submission_fields
表,以简化脚本并轻松根据参考对结果进行排序。

这是完整的脚本:

-- QUERY database

SELECT
    submissions.id AS submission_id,
    submissions.form_id AS form_id,
    forms.title AS form_title,
    GROUP_CONCAT(COALESCE(form_fields.field_id, '') ORDER BY form_fields.id ASC SEPARATOR '|') AS form_fields_field_ids,
    GROUP_CONCAT(COALESCE(fields.label, '') ORDER BY form_fields.id ASC SEPARATOR '|') AS field_labels,
    GROUP_CONCAT(COALESCE(submission_fields.field_id, '') ORDER BY form_fields.id ASC SEPARATOR '|') AS field_ids,
    GROUP_CONCAT(COALESCE(submission_fields.field_value, '') ORDER BY form_fields.id ASC SEPARATOR '|') AS field_values
FROM
    submissions
LEFT OUTER JOIN
    forms
ON
    forms.id = submissions.form_id
LEFT OUTER JOIN
    form_fields
ON
    form_fields.form_id = submissions.form_id
LEFT OUTER JOIN
    fields
ON
    fields.id = form_fields.field_id
LEFT OUTER JOIN
    submission_fields
ON
    submission_fields.submission_id = submissions.id AND fields.id = submission_fields.field_id
WHERE
    submissions.id = 1
GROUP BY
    submissions.id;
© www.soinside.com 2019 - 2024. All rights reserved.