使用多个左连接从不同的表中获取产品详细信息是一个好习惯吗?

发布于 2024-10-03 16:00:32 字数 2227 浏览 4 评论 0原文

我有一个选择查询,因为

    SELECT tbl_product.prod_id,tbl_product.manuf_id, tbl_product.cat_type_id, tbl_product.cat_id, tbl_product.prod_mpn, 
tbl_product.prod_name, tbl_product.prod_model, tbl_product.prod_retail_price, tbl_product.prod_purchase_price, tbl_product.prod_sp_offer_price, tbl_product.prod_stock_qty, tbl_product.prod_ships_in, 
tbl_product.prod_rating, tbl_product.prod_preorder, tbl_category_types.cat_type_name, tbl_category_types.cat_type_seo_name, tbl_category.cat_name, tbl_category.cat_seo_name, tbl_product_images.prod_image, tbl_product_details.prod_short_desc, tbl_product_details.prod_long_desc, tbl_product_seo.prod_seo_title, tbl_product_seo.prod_seo_keywords,tbl_product_details.prod_rel_keywords,tbl_product_seo.prod_seo_desc, tbl_product.network_id, tbl_network.network, tbl_network.network_seo_name, tbl_manufacturer.manuf_id, tbl_manufacturer.manuf_name, tbl_manufacturer.manuf_seo_name, tbl_product.prod_preorder_text
FROM tbl_product    
        LEFT JOIN 
        tbl_category_types ON tbl_category_types.cat_type_id = tbl_product.cat_type_id
        LEFT JOIN 
        tbl_category ON tbl_category.cat_id = tbl_product.cat_id
        LEFT JOIN 
        tbl_product_images ON tbl_product_images.prod_id = tbl_product.prod_id
        LEFT JOIN 
        tbl_product_details ON tbl_product_details.prod_id=tbl_product.prod_id                  
        LEFT JOIN 
        tbl_product_seo ON tbl_product_seo.prod_id = tbl_product.prod_id                    
        LEFT JOIN 
        tbl_network ON tbl_network.network_id = tbl_product.network_id
        LEFT JOIN
        tbl_manufacturer ON tbl_manufacturer.manuf_id = tbl_product.manuf_id                        
        WHERE 
        tbl_product.lang_id = '".$_SESSION["lang_id"]."' AND
        tbl_product.is_comp_phone = 0 AND 
        tbl_product.prod_id = '".$product_id."' AND
        tbl_product_seo.lang_id = '".$_SESSION["lang_id"]."' AND 
        tbl_product_seo.dom_id = '".$_SESSION["domain_id"]."' AND 
        tbl_product_details.lang_id = '".$_SESSION["lang_id"]."' AND 
        tbl_product_details.dom_id = '".$_SESSION["domain_id"]."'  
        LIMIT 1";

我需要使用此查询获取产品详细信息,这种方式是否适合继续? 或者有更好的选择吗?

I have a select query as

    SELECT tbl_product.prod_id,tbl_product.manuf_id, tbl_product.cat_type_id, tbl_product.cat_id, tbl_product.prod_mpn, 
tbl_product.prod_name, tbl_product.prod_model, tbl_product.prod_retail_price, tbl_product.prod_purchase_price, tbl_product.prod_sp_offer_price, tbl_product.prod_stock_qty, tbl_product.prod_ships_in, 
tbl_product.prod_rating, tbl_product.prod_preorder, tbl_category_types.cat_type_name, tbl_category_types.cat_type_seo_name, tbl_category.cat_name, tbl_category.cat_seo_name, tbl_product_images.prod_image, tbl_product_details.prod_short_desc, tbl_product_details.prod_long_desc, tbl_product_seo.prod_seo_title, tbl_product_seo.prod_seo_keywords,tbl_product_details.prod_rel_keywords,tbl_product_seo.prod_seo_desc, tbl_product.network_id, tbl_network.network, tbl_network.network_seo_name, tbl_manufacturer.manuf_id, tbl_manufacturer.manuf_name, tbl_manufacturer.manuf_seo_name, tbl_product.prod_preorder_text
FROM tbl_product    
        LEFT JOIN 
        tbl_category_types ON tbl_category_types.cat_type_id = tbl_product.cat_type_id
        LEFT JOIN 
        tbl_category ON tbl_category.cat_id = tbl_product.cat_id
        LEFT JOIN 
        tbl_product_images ON tbl_product_images.prod_id = tbl_product.prod_id
        LEFT JOIN 
        tbl_product_details ON tbl_product_details.prod_id=tbl_product.prod_id                  
        LEFT JOIN 
        tbl_product_seo ON tbl_product_seo.prod_id = tbl_product.prod_id                    
        LEFT JOIN 
        tbl_network ON tbl_network.network_id = tbl_product.network_id
        LEFT JOIN
        tbl_manufacturer ON tbl_manufacturer.manuf_id = tbl_product.manuf_id                        
        WHERE 
        tbl_product.lang_id = '".$_SESSION["lang_id"]."' AND
        tbl_product.is_comp_phone = 0 AND 
        tbl_product.prod_id = '".$product_id."' AND
        tbl_product_seo.lang_id = '".$_SESSION["lang_id"]."' AND 
        tbl_product_seo.dom_id = '".$_SESSION["domain_id"]."' AND 
        tbl_product_details.lang_id = '".$_SESSION["lang_id"]."' AND 
        tbl_product_details.dom_id = '".$_SESSION["domain_id"]."'  
        LIMIT 1";

I need to fetch the product details using this query, is this way is good to proceed with?
or any better option is possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

∞琼窗梦回ˉ 2024-10-10 16:00:32

你的问题的答案是肯定的,没问题。

唯一的坏处是它可能容易受到 SQL 注入攻击(如果任何人都可以在会话中修改 lang_iddomain_id,他们就会这么做!)

强烈建议您使用参数化例如,使用 PDO 进行查询:

$dbh = new PDO('mysql:dbname=test;host=127.0.0.1','user', 'password'); //assuming mysql
$sql = "SELECT
    tbl_product.prod_id,
    tbl_product.manuf_id,
    tbl_product.cat_type_id,
    tbl_product.cat_id,
    tbl_product.prod_mpn,
    tbl_product.prod_name,
    tbl_product.prod_model,
    tbl_product.prod_retail_price,
    tbl_product.prod_purchase_price,
    tbl_product.prod_sp_offer_price,
    tbl_product.prod_stock_qty,
    tbl_product.prod_ships_in,
    tbl_product.prod_rating,
    tbl_product.prod_preorder,
    tbl_category_types.cat_type_name,
    tbl_category_types.cat_type_seo_name,
    tbl_category.cat_name,
    tbl_category.cat_seo_name,
    tbl_product_images.prod_image,
    tbl_product_details.prod_short_desc,
    tbl_product_details.prod_long_desc,
    tbl_product_seo.prod_seo_title,
    tbl_product_seo.prod_seo_keywords,
    tbl_product_details.prod_rel_keywords,
    tbl_product_seo.prod_seo_desc,
    tbl_product.network_id,
    tbl_network.network,
    tbl_network.network_seo_name,
    tbl_manufacturer.manuf_id,
    tbl_manufacturer.manuf_name,
    tbl_manufacturer.manuf_seo_name,
    tbl_product.prod_preorder_text
FROM tbl_product
LEFT JOIN 
    tbl_category_types ON tbl_category_types.cat_type_id = tbl_product.cat_type_id
LEFT JOIN 
    tbl_category ON tbl_category.cat_id = tbl_product.cat_id
LEFT JOIN 
    tbl_product_images ON tbl_product_images.prod_id = tbl_product.prod_id
LEFT JOIN 
    tbl_product_details ON tbl_product_details.prod_id=tbl_product.prod_id
LEFT JOIN 
    tbl_product_seo ON tbl_product_seo.prod_id = tbl_product.prod_id
LEFT JOIN 
    tbl_network ON tbl_network.network_id = tbl_product.network_id
LEFT JOIN
    tbl_manufacturer ON tbl_manufacturer.manuf_id = tbl_product.manuf_id
WHERE 
    tbl_product.lang_id = :langid AND
    tbl_product.is_comp_phone = 0 AND 
    tbl_product.prod_id = :productid AND
    tbl_product_seo.lang_id = :langid AND 
    tbl_product_seo.dom_id = :domainid AND 
    tbl_product_details.lang_id = :langid AND 
    tbl_product_details.dom_id = :domainid
LIMIT 1";
$stmt = $dbh->prepare($sql)
$stmt->prepare(':langid', $_SESSION["lang_id"]);
$stmt->prepare(':productid', $productid);
$stmt->prepare(':domainid', $_SESSION["domain_id");
if ($stmt->execute()) {
    $row = $stmt->fetch();
    if ($row === false) {
        // no rows
    } else {
        //do something with row data
    }
}

我还清理了它一点。我碰巧喜欢查询中每列一行,但这是个人喜好。

The answer to your question is yes, it's fine.

The only bad thing is that it's potentially vulnerable to SQL injection (if anyone can modify lang_id or domain_id in the session, they will!)

It is highly recommended that you use parametrised queries with PDO, for example:

$dbh = new PDO('mysql:dbname=test;host=127.0.0.1','user', 'password'); //assuming mysql
$sql = "SELECT
    tbl_product.prod_id,
    tbl_product.manuf_id,
    tbl_product.cat_type_id,
    tbl_product.cat_id,
    tbl_product.prod_mpn,
    tbl_product.prod_name,
    tbl_product.prod_model,
    tbl_product.prod_retail_price,
    tbl_product.prod_purchase_price,
    tbl_product.prod_sp_offer_price,
    tbl_product.prod_stock_qty,
    tbl_product.prod_ships_in,
    tbl_product.prod_rating,
    tbl_product.prod_preorder,
    tbl_category_types.cat_type_name,
    tbl_category_types.cat_type_seo_name,
    tbl_category.cat_name,
    tbl_category.cat_seo_name,
    tbl_product_images.prod_image,
    tbl_product_details.prod_short_desc,
    tbl_product_details.prod_long_desc,
    tbl_product_seo.prod_seo_title,
    tbl_product_seo.prod_seo_keywords,
    tbl_product_details.prod_rel_keywords,
    tbl_product_seo.prod_seo_desc,
    tbl_product.network_id,
    tbl_network.network,
    tbl_network.network_seo_name,
    tbl_manufacturer.manuf_id,
    tbl_manufacturer.manuf_name,
    tbl_manufacturer.manuf_seo_name,
    tbl_product.prod_preorder_text
FROM tbl_product
LEFT JOIN 
    tbl_category_types ON tbl_category_types.cat_type_id = tbl_product.cat_type_id
LEFT JOIN 
    tbl_category ON tbl_category.cat_id = tbl_product.cat_id
LEFT JOIN 
    tbl_product_images ON tbl_product_images.prod_id = tbl_product.prod_id
LEFT JOIN 
    tbl_product_details ON tbl_product_details.prod_id=tbl_product.prod_id
LEFT JOIN 
    tbl_product_seo ON tbl_product_seo.prod_id = tbl_product.prod_id
LEFT JOIN 
    tbl_network ON tbl_network.network_id = tbl_product.network_id
LEFT JOIN
    tbl_manufacturer ON tbl_manufacturer.manuf_id = tbl_product.manuf_id
WHERE 
    tbl_product.lang_id = :langid AND
    tbl_product.is_comp_phone = 0 AND 
    tbl_product.prod_id = :productid AND
    tbl_product_seo.lang_id = :langid AND 
    tbl_product_seo.dom_id = :domainid AND 
    tbl_product_details.lang_id = :langid AND 
    tbl_product_details.dom_id = :domainid
LIMIT 1";
$stmt = $dbh->prepare($sql)
$stmt->prepare(':langid', $_SESSION["lang_id"]);
$stmt->prepare(':productid', $productid);
$stmt->prepare(':domainid', $_SESSION["domain_id");
if ($stmt->execute()) {
    $row = $stmt->fetch();
    if ($row === false) {
        // no rows
    } else {
        //do something with row data
    }
}

I also cleaned it up a bit. I happen to like one line per column in a query, but that's personal preference.

枫以 2024-10-10 16:00:32

是的,没关系。但请记住,对于 MySQL 来说,LEFT JOIN 更难优化,因此为了性能考虑,请尽可能使用 INNER JOIN。

Yes, that is OK. But please keep in mind that for MySQL LEFT JOINs are harder to optimize, so for performance sake use INNER JOINs where possible.

你另情深 2024-10-10 16:00:32

对我来说似乎是一个很好的询问。

Seems like a fine query to me.

阳光的暖冬 2024-10-10 16:00:32

错误的查询,您已通过在 where 子句中使用其中一些左联接将它们转换为内联接。您需要将 tbl_product_seo 和 tbl_product_details 的过滤条件移至左连接的 ON 子句。

Bad query, you have converted some of those left joins to inner joins by using them in the where clause. You need to move the filtering conditions for tbl_product_seo and tbl_product_details to the ON clause of the left joins.

爱你是孤单的心事 2024-10-10 16:00:32

正如 HLGEM 所说,左联接在其中一些表上毫无意义,只要您在 where 子句中使用它们,优化器就会将它们转换为 INNER JOINS。

原因是,您通常使用 LEFT JOIN 来获取一个表中的记录以及第二个表中存在的任何记录,如果第二个表中不存在记录,这将返回 NULL。

使用 WHERE 子句限制第二个表中的项目时,它永远不会返回 NULL,因此 LEFT JOINS 完全没有意义

As HLGEM says the left joins are pointless on some of those tables, as soon as you used them in the where clause the Optimizer will turn them into INNER JOINS.

Reason being is that you usually use a LEFT JOIN to get records in one table and any records if they exist in a second table, this will bring back NULLS where no record exists in the second table.

With using a WHERE clause to restrict items in the second table, it can never return NULLS, therefore a LEFT JOINS is utterly pointless

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文