php - 将工作负载从 PHP 转移到 MySQL

标签 php mysql

我当前有两个按顺序执行的查询。第一个查询从数据库中提取几行,第二个查询使用这些行中的一个值执行。我只对第一个查询中的行感兴趣,我知道第二个查询将返回大于 0 的值。我的第一个表中可能有数千行,所以我宁愿在 MySQL 中进行过滤,而不是在PHP,我认为它更快。

第一个查询如下

SELECT 
    *
FROM 
    wp_invoices 
WHERE 
    deleted = 0

第二个查询如下:

SELECT COUNT(*) FROM wp_users A
    INNER JOIN wp_usermeta B ON (A.ID = B.user_id)  
    LEFT JOIN wp_invoices_records C ON (A.ID = C.uid 
        AND C.invoice_id = %d 
        AND C.status != 100) 
WHERE (B.meta_key = 'wp_capabilities' AND CAST(B.meta_value AS CHAR) LIKE '%%\"subscriber\"%%') 
    AND (C.uid IS NOT NULL)

两个查询单独工作,这不是问题。目前,第二个查询中的 %d 已被 PHP 替换,PHP 会为每行插入 wp_invoices.id 值。

理想情况下,我想要一个仅返回 wp_invoices 中的行的查询,其中第二个查询将返回大于 0 的值。此时我对第二个查询的行不感兴趣,只对行数感兴趣找到了。

我的表结构如下:http://sqlfiddle.com/#!9/466cb

这就是我目前在 PHP 中所做的,来处理所有这些。请记住,编写此代码是为了澄清这篇文章,我使用已弃用的 MySQL 函数,因为我不再经常编写 PHP,也没有真正研究过 mysqli,也没有检查此代码是否实际运行。它应该可以让您更好地了解我目前正在做什么。

<?php

    /* Example code. I am not using mysql_ functions in my own solution, I just 
       know these functions by heart. Assume a database connection is already 
       established */

    /* Refer to this as QUERY 1 */
    $result = mysql_query("SELECT * FROM wp_invoices WHERE deleted = 0");

    /* Loop over all invoices (this is not an invoice 'record'. These are 
       the invoice definitions, not the actual instances that people received */
    while($row = mysql_fetch_assoc($result)) {

        /* Refer to this as QUERY 2 */
        $count_result = mysql_query(sprintf("
            SELECT 
                COUNT(*) AS count
            FROM wp_users A 
            INNER JOIN wp_usermeta B ON (A.ID = B.user_id)  
            LEFT JOIN wp_invoices_records C ON (A.ID = C.uid 
                AND C.invoice_id = %d 
                AND C.status != 100) 
            WHERE (B.meta_key = 'wp_capabilities' 
                AND CAST(B.meta_value AS CHAR) LIKE '%%\"subscriber\"%%') 
                AND (C.uid IS NOT NULL)", $row['id']));

        if(mysql_result($count_result, 0) > 0) {

            /* Here I would pull all data I would need for this invoice. $row
               contains all the information about the invoice, $invoice_record
               will contain all the information for this particular user about
               this invoice*/
            $invoice_records = mysql_query(sprintf("
                SELECT
                    A.ID AS id,
                    A.display_name,
                    C.id AS received,
                    DATE_FORMAT(C.received_on, '%%d-%%m-%%Y') AS received_on,
                    C.status,
                    A.user_email,
                    C.price,
                    (SELECT meta_value FROM wp_usermeta WHERE meta_key = 'first_name' 
                        AND user_id = A.ID) AS first_name,
                    (SELECT meta_value FROM wp_usermeta WHERE meta_key = 'tssnvgsl' 
                        AND user_id = A.ID) AS insertion,
                    (SELECT meta_value FROM wp_usermeta WHERE meta_key = 'last_name' 
                        AND user_id = A.ID) AS last_name
                FROM wp_users A
                INNER JOIN wp_usermeta B ON (A.ID = B.user_id)  
                LEFT JOIN wp_invoices_records C ON (A.ID = C.uid 
                    AND C.invoice_id = %d 
                    AND C.status != 100) 
                WHERE (B.meta_key = 'wp_capabilities' 
                    AND CAST(B.meta_value AS CHAR) LIKE '%%\"subscriber\"%%') 
                    AND (C.uid IS NOT NULL)", $row['id']));

            while($invoice_record = mysql_fetch_assoc($invoice_records)) {
                /* Perform logic to see if this person should receive a reminder */
            }
        }
    }

?>

不过,我试图实现的目标是:

<?php

        $result = mysql_query(/* here a query that pulls all rows from QUERY 1
                where QUERY 2 would have returned a count higher than 2 */);

        while($row = mysql_fetch_assoc($result)) {
                /* Now here I should be 100% sure that every $row has at least one
                   "pending" invoice record, that has not yet been paid and has a
                   status of < 100 */
        }

?>

最佳答案

好吧。我一直在绞尽脑汁地盯着你的过程,我认为它开始有意义了。如果我没有记错的话,您应该能够消除 query1 和 query2 并将逻辑移至第三个查询的 LEFT JOIN 中,如下所示。

SELECT
   A.ID AS id,
   A.display_name,
   C.id AS received,
   DATE_FORMAT(C.received_on, '%%d-%%m-%%Y') AS received_on,
   C.status,
   A.user_email,
   C.price,
   (SELECT meta_value FROM wp_usermeta WHERE meta_key = 'first_name' 
           AND user_id = A.ID) AS first_name,
   (SELECT meta_value FROM wp_usermeta WHERE meta_key = 'tssnvgsl' 
           AND user_id = A.ID) AS insertion,
   (SELECT meta_value FROM wp_usermeta WHERE meta_key = 'last_name' 
           AND user_id = A.ID) AS last_name
FROM wp_users A
INNER JOIN wp_usermeta B ON (A.ID = B.user_id)  
LEFT JOIN wp_invoices_records C ON (A.ID = C.uid 
   AND C.invoice_id IN (SELECT id FROM wp_invoices WHERE deleted = 0)
   AND C.status != 100) 
WHERE (B.meta_key = 'wp_capabilities' 
   AND CAST(B.meta_value AS CHAR) LIKE '%%\"subscriber\"%%') 
   AND (C.uid IS NOT NULL)"

这个查询,而不是每次都必须为每条记录运行,并且通过php在你的LEFT JOIN中添加$row['id'],我使用带有子选择的MySQL IN功能。这使您能够仅加入已删除的 wp_invoices 记录。

关于php - 将工作负载从 PHP 转移到 MySQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33828419/

相关文章:

javascript - 一页上有多个谷歌可视化表

php - undefined variable : $sameday at somthing.php

mysql - 生成 ER 图并导出到一些交互式 map

php - 如何制作一个画廊,其中使用的图像来自 mysql 数据库?

mysql - 由于日期时间默认值无效,无法添加新列

php - MySql 比较两个列表

php - 如何在 PhpStorm 上设置数据库?

php - CakePHP 的外部认证/授权

php - 如何使用 YII 框架指定一个 SEO 友好的 url,比如 twitter www.twitter.com/<name>

MySQL 5.5 SELECT DISTINCT - 如何返回多个没有查询重复的列?