来自另一个的MySQL Update表,忽略重复

时间:2014-09-07 13:15:06

标签: mysql

提前感谢您的所有帮助!

我有2个表:付款和付款_options。付款在结帐时设置,但通过user_id与payment_options相关联。

以下是付款示例:

# id,   user_id, order_id, subtotal, tax,  tip,  total, payment_method, payment_details
641481, 736471,  641851,   14.88,    1.32, 1.86, 8.06,  Credit Card,    ending in
641431, 109351,  641801,   10.54,    0.94, 1.32, 2.80,  Credit Card,    ending in
641381, 734171,  641751,   22.02,    1.95, 2.75, 26.72, Credit Card,    ending in
641351, 722321,  641711,   17.48,    1.55, 3.00, 22.03, Credit Card,    ending in
641201, 721511,  641581,   18.14,    1.61, 2.27, 22.02, Credit Card,    ending in

Payment_options示例(示例信息,令牌,cc_masked等,所有年份都已编制完成):

# id,  user_id, cc_type, cc_token,            cc_masked,        cc_exp_month, cc_exp_year,
13371, 736471,  Visa,    fo7i-zr1w-9rsw-c6ty, XXXXXXXXXXXX3821,  7,            2015
9951,  109351,  Visa,    r3t6-co2i-i0ao-xz8d, XXXXXXXXXXXX9405,  4,            2016
9941,  734171,  Amex,    bd86-96t0-3j0g-a88g, XXXXXXXXXXX3004,   8,            2017
9931,  722321,  Maste,   o6ow-td7c-lfk0-b47e, XXXXXXXXXXXX5818,  1,            2016
9921,  721511,  Visa,    ysjp-5o4w-n3ls-y1ix, XXXXXXXXXXXX5297,  3,            2017

我想要完成的是将cc_typecc_masked合并到表格payments中,如下所示:

# id,   user_id, order_id, subtotal, tax,  tip,  total, payment_method, payment_details
641481, 736471,  641851,   14.88,    1.32, 1.86, 8.06,  Credit Card,    Visa ending in 3821
641431, 109351,  641801,   10.54,    0.94, 1.32, 2.80,  Credit Card,    Visa ending in 9405
641381, 734171,  641751,   22.02,    1.95, 2.75, 26.72, Credit Card,    Amex ending in 3004
641351, 722321,  641711,   17.48,    1.55, 3.00, 22.03, Credit Card,    Master ending in 5818
641201, 721511,  641581,   18.14,    1.61, 2.27, 22.02, Credit Card,    Visa ending in 5297

出现的问题是有些人保存了多张卡。由于payment_options允许非唯一user_id。如果我在user_id = user_id的某个表中进行直接更新,我担心会覆盖这些值。

select `id`, `user_id`, `name`, cc_type, cc_masked,
    (select count(*) 
    from payment_options
    where user_id = count_table.user_id
    group by `user_id`)
    as count
from payment_options as count_table having count > 1

结果如下:

# id,  user_id, cc_type, cc_masked,         count
15551, 736471,  Visa,    XXXXXXXXXXXX3821,  2
15741, 736471,  Visa,    XXXXXXXXXXXX5708,  2
15961, 510911,  Master,  XXXXXXXXXXXX3770,  2
16491, 510911,  Amex,    XXXXXXXXXXX3005,   2

如您所见,user_id = 736471已保存多张Visa卡。 paymentspayment_options只能由user_id关联。

这让我相信我不能只更新表1:1但需要某种条款来更新user_id已保存多张卡的行以避免错误更新

编辑:为了清晰起见。

根据@VMai我将使用以下MySQL查询,只需发布​​以仔细检查

    SELECT CONCAT(cc_type, ' ending in ', RIGHT(cc_masked, 4)) 
    FROM paymen_options
    WHERE payment_options.user_id NOT EXISTS = (
          SELECT payment_options.user_id, (SELECT COUNT (*)
                 FROM payment_options
                 WHERE payment_options.user_id = count_table.user.id
                 GROUP BY user_id)
                 AS count
            FROM payment_options as count_table
            HAVING count > 1
          )
    );

这看起来是对的吗? Workbench在NOT EXISTS附近给我一个错误1064,我现在正在努力争取。

1 个答案:

答案 0 :(得分:0)

试试这个。无法测试,因此请运行数据库和备份的副本!

// uses PHP Database Objects (PDO) - will need adapting for use with mysqli instead
// add your host, database, username and password below
$db_connection = new PDO('mysql:host='. $DB_HOST .';dbname='. $DB_NAME . ';charset=utf8', $DB_USER, $DB_PASS);

$select_query  = 'SELECT user_id, CONCAT(cc_type, ' ending in ', RIGHT(cc_masked, 4)) AS cc,';
$select_query .= '(SELECT COUNT(*) FROM payment_options WHERE user_id = count_table.user_id GROUP BY `user_id`) AS count ';
$select_query .= 'FROM payment_options AS count_table HAVING count = 1';

// use LIMIT in SQL statement if large tables,
// otherwise your PHP script might timeout if you try to do too much

$SELECT = $db_connection->prepare($select_query);
$SELECT->execute();

$UPDATE = $db_connection->prepare('UPDATE payments SET payment_details=:payment_details WHERE user_id=:user_id');
$count = 0;
$success = true;

while($row = $SELECT->fetch(PDO::FETCH_ASSOC)) {
    $UPDATE->bindValue(':payment_details', $row['cc'], PDO::PARAM_STR);
    $UPDATE->bindValue(':user_id', $row['user_id'], PDO::PARAM_INT);
    $UPDATE->execute();

    if($UPDATE->errorCode() != 0) {
        echo "error: ".$UPDATE->errorInfo()[2]."<br><br>";
        $success = false;
        break;
    }
    $count++;
}
if($success)
    echo "<b>SUCCESS!<b>";
else
    echo "<b>FAILED!<b> (see error message above)";

echo "<br><br>Updated ".number_format($count)." rows!";