【问题标题】:Update MySQL table based on results for joining to tables根据加入表的结果更新 MySQL 表
【发布时间】:2014-07-11 22:12:19
【问题描述】:

我有三个表,电子邮件、person_details 和 data_providers。基本上我所有的用户 id、email 和当前分配的 data_providers_id 都存储在 emails 表中。

第二个表 person_details 包含由多个数据提供者收集的人口统计信息,每一行由与 emails.id 相关的 emails_id 标识,data_providers_id 与第三个表 data_providers.id 相关

第三个表 data_providers 包含我的每个数据提供者 ID、名称和优先级。

基本上,可以从多个来源收集用户信息,我需要UPDATE emails set data_providers_id = 基于将加入 person_details 表和 data_providers 表的选择,按 data_providers.precedence DESC 然后 person_details.import_date ASC 排序并使用第一个值(最高优先级,然后是最早的 import_date)。

我试图构建查询,但我的子查询返回不止一行。这个查询有点超出我的想象,希望对复杂查询更有经验的人能够为我指出正确的方向。

UPDATE emails 
SET emails.data_providers_id = 
    SELECT person_details.data_providers_id 
    FROM person_details 
    LEFT JOIN data_providers ON person_details.data_providers_id = data_providers.id
    ORDER BY data_providers.percent_payout ASC, person_details.import_date ASC ;

如果有帮助,这里是有关这三个表的一些详细信息。任何指导将不胜感激。在此先感谢:)

电子邮件表:

+-------------------+---------------------+------+-----+---------------------+----------------+
| Field             | Type                | Null | Key | Default             | Extra          |
+-------------------+---------------------+------+-----+---------------------+----------------+
| id                | int(11) unsigned    | NO   | PRI | NULL                | auto_increment |
| data_providers_id | tinyint(3) unsigned | NO   | MUL | NULL                |                |
| email             | varchar(255)        | NO   | UNI | NULL                |                |
+-------------------+---------------------+------+-----+---------------------+----------------+

person_details:

+-------------------+---------------------+------+-----+---------------------+-------+
| Field             | Type                | Null | Key | Default             | Extra |
+-------------------+---------------------+------+-----+---------------------+-------+
| emails_id         | int(11) unsigned    | NO   | PRI | NULL                |       |
| data_providers_id | tinyint(3) unsigned | NO   | PRI | NULL                |       |
| fname             | varchar(255)        | YES  |     | NULL                |       |
| lname             | varchar(255)        | YES  |     | NULL                |       |
| address_line1     | text                | YES  |     | NULL                |       |
| address_line2     | text                | YES  |     | NULL                |       |
| city              | varchar(255)        | YES  |     | NULL                |       |
| state             | varchar(2)          | YES  |     | NULL                |       |
| zip5              | varchar(5)          | YES  |     | NULL                |       |
| zip4              | varchar(4)          | YES  |     | NULL                |       |
| home_phone        | varchar(10)         | YES  |     | NULL                |       |
| mobile_phone      | varchar(10)         | YES  |     | NULL                |       |
| work_phone        | varchar(10)         | YES  |     | NULL                |       |
| dob               | date                | YES  |     | NULL                |       |
| gender            | varchar(1)          | YES  |     | NULL                |       |
| ip_address        | varchar(15)         | NO   |     | NULL                |       |
| source            | varchar(255)        | NO   |     | NULL                |       |
| optin_datetime    | datetime            | NO   | MUL | NULL                |       |
| import_date       | timestamp           | NO   |     | 0000-00-00 00:00:00 |       |
+-------------------+---------------------+------+-----+---------------------+-------+

data_providers 表:

+-----------------+---------------------+------+-----+---------+----------------+
| Field           | Type                | Null | Key | Default | Extra          |
+-----------------+---------------------+------+-----+---------+----------------+
| id              | tinyint(3) unsigned | NO   | PRI | NULL    | auto_increment |
| name            | varchar(255)        | NO   |     | NULL    |                |
| precedence      | int(2)              | YES  |     | 0       |                |
+-----------------+---------------------+------+-----+---------+----------------+

【问题讨论】:

  • 在没有 WHERE...IS NULL 语句的情况下,UPDATES 上的 LEFT JOIN 有点奇怪
  • @Strawberry,感谢您的提醒。幸运的是,在这张表上,查询所需的所有列都不是 NULL。
  • hm - 你没抓住重点

标签: mysql email sql-update subquery left-join


【解决方案1】:

要将SELECT 用作表达式,您必须将其放在括号中。要获得第一个值,请使用LIMIT 1

UPDATE emails 
SET emails.data_providers_id = (
    SELECT person_details.data_providers_id 
    FROM person_details 
    LEFT JOIN data_providers ON person_details.data_providers_id = data_providers.id
    WHERE person_details.emails_id = emails.id
    ORDER BY data_providers.percent_payout ASC, person_details.import_date ASC
    LIMIT 1) ;

【讨论】:

  • 您的选择完美运行,因为它返回单行,但是它将使用相同的单行结果更新电子邮件表中的每条记录。我需要根据 emails.id 匹配 person_details.emails_id 独立更新 emails 表的每一行。
  • 我已将答案更改为使用相关子查询。
  • 不好意思,回头看了下确实一点都不清楚的问题。非常感谢您的帮助,非常感谢!现在看起来很简单,你把它列出来了,不知道为什么我一直被这个查询绊倒。
猜你喜欢
  • 2016-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多