使用2个内部选择优化更新sql语句

时间:2018-04-03 08:43:08

标签: mysql sql

我想知道如何优化sql查询。

表结构如下:

委员会

+---------------------------+----------------------------------------------+------+-----+---------+----------------+
| Field                     | Type                                         | Null | Key | Default | Extra          |
+---------------------------+----------------------------------------------+------+-----+---------+----------------+
| id                        | int(11)                                      | NO   | PRI | NULL    | auto_increment             |
| network_commission        | int(11)                                      | YES  |     | NULL    |                |
+---------------------------+----------------------------------------------+------+-----+---------+----------------+

AdvertiserBalanceTransactions

+---------------------+---------------+------+-----+---------+----------------+
| Field               | Type          | Null | Key | Default | Extra          |
+---------------------+---------------+------+-----+---------+----------------+
| id                  | int(11)       | NO   | PRI | NULL    | auto_increment |
| commission_id       | int(11)       | YES  | MUL | NULL    |                |
| transaction_type    | varchar(255)  | YES  |     | NULL    |                |
| amount              | decimal(10,2) | YES  |     | 0.00    |                |
| currency_code       | varchar(3)    | YES  |     | NULL    |                |
| created_at          | datetime      | NO   |     | NULL    |                |
| updated_at          | datetime      | NO   |     | NULL    |                |
+---------------------+---------------+------+-----+---------+----------------+

规则
AdvertiserBalanceTransactions只能有两种类型:' new_commissions'或者' nt_commission'。类型' new_commissions'只有在'nt_commission'可以出现n次(至少一次至多一次,具有不同的值)。

更新佣金表network_commission列
network_commission以值NULL开头,并且必须使用以下表达式填充:第一个创建的类型为&nt_commission' nt_commission'的AdvertiserBalanceTransaction的值(金额)。 * 100 /类型' new_commission'的AdvertiserBalanceTransaction的值(金额)。

以下查询执行此操作:

update commissions set commissions.network_commission=(
 select t.amount * 100 / new_com_tran.amount 
 from advertiser_balance_transactions new_com_tran,
      (select nt_com_tran.amount, nt_com_tran.commission_id
         from advertiser_balance_transactions nt_com_tran
        where nt_com_tran.transaction_type = 'nt_commission'
        order by created_at asc limit 1) t
 where commissions.id=new_com_tran.commission_id
 AND new_com_tran.transaction_type = 'new_commissions' 
 AND t.commission_id=commissions.id) 
where commissions.amount != 0;

示例数据
佣金:

+--------+--------------------+
| id     | network_commission |
+--------+--------------------+
| 887755 |               NULL |
| 887752 |               NULL |
| 887751 |               NULL |
| 887750 |               NULL |
| 887749 |               NULL |
| 887748 |               NULL |
| 887747 |               NULL |
| 887746 |               NULL |
| 887745 |               NULL |
| 887744 |               NULL |
+--------+--------------------+

AdvertiserBalanceTransactions:

+---------+---------------+------------------+--------+---------------+---------------------+---------------------+
| id      | commission_id | transaction_type | amount | currency_code | created_at          | updated_at          |
+---------+---------------+------------------+--------+---------------+---------------------+---------------------+
| 1432047 |        887744 | new_commissions  |  -0.30 | RON           | 2018-01-22 09:09:54 | 2018-01-22 09:09:54 |
| 1432048 |        887744 | nt_commission    |  -0.12 | RON           | 2018-01-22 09:09:54 | 2018-01-22 09:09:54 |
| 1432048 |        887744 | nt_commission    |  -0.23 | RON           | 2018-01-22 09:10:54 | 2018-01-22 09:10:54 |
| 1432049 |        887745 | new_commissions  |  -0.30 | RON           | 2018-01-22 09:09:57 | 2018-01-22 09:09:57 |
| 1432050 |        887745 | nt_commission    |  -0.12 | RON           | 2018-01-22 09:09:57 | 2018-01-22 09:09:57 |
| 1432051 |        887746 | new_commissions  |  -0.30 | RON           | 2018-01-22 11:06:23 | 2018-01-22 11:06:23 |
| 1432052 |        887746 | nt_commission    |  -0.12 | RON           | 2018-01-22 11:06:23 | 2018-01-22 11:06:23 |
| 1432053 |        887747 | new_commissions  |  -0.30 | RON           | 2018-01-22 11:09:35 | 2018-01-22 11:09:35 |
| 1432054 |        887747 | nt_commission    |  -0.12 | RON           | 2018-01-22 11:09:35 | 2018-01-22 11:09:35 |
| 1432055 |        887748 | new_commissions  |  -0.30 | RON           | 2018-01-22 11:11:09 | 2018-01-22 11:11:09 |
| 1432056 |        887748 | nt_commission    |  -0.12 | RON           | 2018-01-22 11:11:09 | 2018-01-22 11:11:09 |
| 1432057 |        887749 | new_commissions  |  -0.30 | RON           | 2018-01-22 11:19:10 | 2018-01-22 11:19:10 |
| 1432058 |        887749 | nt_commission    |  -0.12 | RON           | 2018-01-22 11:19:10 | 2018-01-22 11:19:10 |
| 1432059 |        887750 | new_commissions  |  -0.30 | RON           | 2018-01-22 11:22:21 | 2018-01-22 11:22:21 |
| 1432060 |        887750 | nt_commission    |  -0.12 | RON           | 2018-01-22 11:22:21 | 2018-01-22 11:22:21 |
| 1432061 |        887751 | new_commissions  |  -0.30 | RON           | 2018-01-23 10:29:48 | 2018-01-23 10:29:48 |
| 1432062 |        887751 | nt_commission    |  -0.12 | RON           | 2018-01-23 10:29:48 | 2018-01-23 10:29:48 |
| 1432063 |        887752 | new_commissions  |  -0.30 | RON           | 2018-01-23 12:55:11 | 2018-01-23 12:55:11 |
| 1432064 |        887752 | nt_commission    |  -0.12 | RON           | 2018-01-23 12:55:11 | 2018-01-23 12:55:11 |
| 1432069 |        887755 | new_commissions  |  -2.10 | RON           | 2018-02-22 11:38:45 | 2018-02-22 11:38:45 |
| 1432070 |        887755 | nt_commission    |  -0.84 | RON           | 2018-02-22 11:38:45 | 2018-02-22 11:38:45 |
+---------+---------------+------------------+--------+---------------+---------------------+---------------------+

无论如何我可以优化此更新查询吗?

2 个答案:

答案 0 :(得分:1)

我建议使用JOINS

update commissions c
LEFT JOIN advertiser_balance_transactions new_t 
    ON c.id=new_t.commission_id AND new_t.transaction_type='new_commissions'
LEFT JOIN advertiser_balance_transactions first_nt_t 
    ON c.id=first_nt_t.commission_id AND first_nt_t.transaction_type='nt_commission' 
        AND first_nt_t.created_at=(SELECT MIN(created_at) 
                       FROM advertiser_balance_transactions t3 
                       WHERE t3.commission_id=c.id AND transaction_type='nt_commission')
set commissions.network_commission = first_nt_t.amount * 100 / new_t.amount

答案 1 :(得分:0)

你可以 JOIN 将两个选择合二为一,根据你的DBMS甚至完全消除选择,因为一些(例如SYBASE)允许 FROM 中的多个表。