如何将具有键值对的元表作为父行加入

时间:2019-04-07 08:07:35

标签: mysql sql eloquent key-value

嗨,我有这个表结构

form_submissions

+------+----------------------------------+
| id   | form_id                          |
+------+----------------------------------+
| 3812 | 00184e51e26a41e4a197035b62a1e07a |
| 3815 | 00184e51e26a41e4a197035b62a1e07a |
+------+----------------------------------+

form_submission_datas

+--------+--------------------+-----------+----------------+
| id     | form_submission_id | key       | value          |
+--------+--------------------+-----------+----------------+
| 534670 |              65952 | ip        | 192.168.255.10 |
| 534669 |              65952 | email     | NULL           |
| 534668 |              65952 | city      | NULL           |
| 534667 |              65952 | phone     | 123-123-1234   |
| 534666 |              65952 | full_name | גל             |
+--------+--------------------+-----------+----------------+

我的目标结果是这样的

+--------------------+----------------+-------+------+--------------+-----------+
| form_submission_id | ip             | email | city | phone        | full_name |
+--------------------+----------------+-------+------+--------------+-----------+
|              65952 | 192.168.255.10 | NULL  | NULL | 123-123-1234 | gal       |
+--------------------+----------------+-------+------+--------------+-----------+

我的键值对是不可预测的,因此我无法选择...作为“电子邮件”等。

现在我在PHP中执行此操作,但是我的表单包含5-7k +行,这真的很不礼貌,每个页面加载需要60-70秒,然后需要2 GB以上的内存 我很想让MySQL为我做这件事。

2 个答案:

答案 0 :(得分:0)

您可以使用条件聚合

SELECT
    form_submission_id,
    MAX(CASE WHEN key = 'ip' THEN value END) ip,
    MAX(CASE WHEN key = 'email' THEN value END) email,
    MAX(CASE WHEN key = 'city' THEN value END) city,
    MAX(CASE WHEN key = 'phone' THEN value END) phone,
    MAX(CASE WHEN key = 'full_name' THEN value END) full_name
FROM form_submission_datas
GROUP BY form_submission_id

这确实需要您事先知道表中可能存在的键的列表;这是因为SQL查询必须返回一组固定列。要使其动态化,您需要使用动态SQL ,这可能超出了您的问题范围。

注意:就您而言,您不需要提交表即可生成预期结果。如果您还需要从该表中恢复一些信息,则需要向查询中添加一个简单的JOIN。

答案 1 :(得分:0)

对于键值结构,您可以对每个键值对使用join

  select  a.form_submission_id, a.ip
    , b.value as email
    , c.value as city
    , d.value as phone 
    , e.value as full_name
  from  form_submission_datas a 
  inner join  form_submission_datas b  = a.form_submission_id = b.form_submission_id 
    AND b.key = 'email'
  inner join  form_submission_datas c  = a.form_submission_id = c.form_submission_id 
    AND c.key = 'city'
  inner join  form_submission_datas d  = a.form_submission_id = d.form_submission_id 
    AND d.key = 'phone'
  inner join  form_submission_datas e  = a.form_submission_id = e.form_submission_id 
    AND e.key = 'full_name'
  where a.key ='ip' 
  and form_submission_id = 65952