我有一个选择查询
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";
我需要使用此查询获取产品详细信息,这种方式是否可以继续? 还是有更好的选择?
答案 0 :(得分:2)
你的问题的答案是肯定的,没关系。
唯一不好的是它可能容易受到SQL注入攻击(如果有人可以在会话中修改lang_id
或domain_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
}
}
我也把它清理了一下。我碰巧在查询中每列一行,但这是个人偏好。
答案 1 :(得分:1)
是的,没关系。但请记住,对于MySQL LEFT JOIN更难以优化,因此为了性能,尽可能使用INNER JOIN。
答案 2 :(得分:0)
对我来说似乎很好。
答案 3 :(得分:0)
错误查询,您已将其中一些左连接转换为内连接,方法是在where子句中使用它们。您需要将tbl_product_seo和tbl_product_details的过滤条件移动到左连接的ON子句。
答案 4 :(得分:0)
正如HLGEM所说,左边连接在某些表上是没有意义的,只要你在where子句中使用它们,优化器就会将它们变成INNER JOINS。
原因是您通常使用LEFT JOIN来获取一个表中的记录以及任何记录(如果它们存在于第二个表中),这将带回NULLS,其中第二个表中不存在记录。
使用WHERE子句限制第二个表中的项目,它永远不会返回NULLS,因此LEFT JOINS完全没有意义