【问题标题】:Combine multiple MySql queries into a single query将多个 MySql 查询合并为一个查询
【发布时间】:2010-11-01 15:17:16
【问题描述】:

我正在尝试解决第二天的问题,但还没有成功。

我的目标是:

对于某些分类术语 ID(例如 1),我需要获取至少一个属于该术语 ID(tid 1)的节点的图像字段文件路径

以下是我需要的三个查询。一切正常,但我知道它看起来很丑,而且我敢肯定,存在很大的性能问题。

$childterm = 10; // Taxonomy term ID
$result = db_fetch_array(db_query("SELECT node.vid FROM node JOIN 
                                   term_node ON  node.vid=term_node.vid WHERE  
       term_node.tid=$childterm AND 
                                   node.type= 'product' LIMIT 0,1"));           

$nvid = $result['vid']; // Extracting node VID by term ID that will be used futher 

$result = db_fetch_array(db_query("SELECT field_image_cache_fid FROM
                                   content_field_image_cache WHERE
       vid = '%d'", $nvid));

$fid = $result['field_image_cache_fid']; // Extracting file ID from array

$result = db_fetch_array(db_query("SELECT filepath FROM files WHERE
                                   files.fid = '%d'", $fid));           

$filepath = $result['filepath']; // Finally. Extracting file path from array

请看图。

如何改进查询?我可以只使用一个 sql 查询来获取文件路径值吗?

提前致谢。

【问题讨论】:

    标签: sql mysql drupal join


    【解决方案1】:

    这样的事情应该可以工作。

    $sql = "SELECT f.filepath FROM {node} AS n
    INNER JOIN {term_node} AS t ON t.nid = n.nid
    INNER JOIN {content_field_image_cache} as c ON c.nid = n.nid
    INNER JOIN {files} AS f on f.fid = c.fid
    WHERE n.type = '%s'
    AND t.tid = %d;"
    

    $result = db_query($sql, $node_type, $tid);

    请注意,您应该使用

    获取有关内容表名称的信息
    $db_info = content_database_info(content_fields($field_name));
    

    原因是如果你从多个值切换到多个值,SQL 会中断,除非你使用这种方法来额外的表和列名。

    【讨论】:

    • 我认为这些应该是内连接,而不是左外连接。
    • @Mark B:没错,旧习惯很难改掉。
    • 另外,请注意 CCK,提供诸如 content_field_image_cache 之类的表的模块可能(因此将)随意更改数据库布局。该表可能会在配置更改时消失。像你这样的查询将会中断。您至少可以为此添加一些文档。或者,更可靠的是,在 hook_requirements() 中提供检查。
    【解决方案2】:

    我接受了@googletorp 的回答。尽管他的解决方案不是 100% 适合我,但它指向了正确的方向。

    这是正确的代码:

    $childterm = 10;// taxonomy term
    $nodetype = 'product';// node type
    $sql = "SELECT f.filepath FROM node n 
            INNER JOIN term_node tn ON tn.vid = n.vid  
            INNER JOIN content_field_image_cache cf ON cf.vid = n.vid 
            INNER JOIN files f ON f.fid = cf.field_image_cache_fid 
            WHERE n.type = $nodetype AND tn.tid = $childterm LIMIT 0, 1";
            $result = db_fetch_array(db_query($sql));
        $filepath = $result['filepath']; // image path
    

    谢谢,你们都是很酷的人!

    【讨论】:

    • 在这种情况下,加入vidnid 没有区别,因为vid 仅用于节点的正文内容修订。同样在 drupal 中,您应该使用占位符,就像我演示的那样,帮助防止 SQL 注入。同样在这种情况下,由于您只得到一个结果,您应该使用db_result 而不是db_fetch_array
    猜你喜欢
    • 2016-04-02
    • 1970-01-01
    • 2015-02-02
    • 2016-02-05
    • 1970-01-01
    • 2012-11-18
    • 1970-01-01
    相关资源
    最近更新 更多