2010-11-18 28 views
1

我有一個選擇查詢作爲使用多個左連接從不同的表中獲取產品細節是否是一種好的做法?

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

你知道,一切都在一個數據庫管理系統是一個表或視圖,因此「 tbl_'的前綴很不實際?它不傳遞任何有用的信息,並混亂名稱。同樣,你的SQL可以通過精心選擇的表別名(短名稱)而不是全名來更易讀。 – 2010-11-18 16:11:38

回答

2

你的問題的答案是肯定的,沒關係。

唯一不好的是,它可能會遭受SQL注入(如果任何人都可以修改會話lang_iddomain_id,他們會!)

強烈建議您使用parametrised查詢與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 
    } 
} 

我也清理了一下。我碰巧在查詢中每列有一行,但這是個人偏好。

0

看起來像一個罰款查詢給我。

1

是的,沒關係。但請記住,對於MySQL LEFT JOIN來說,難以優化,所以爲了性能,儘可能使用INNER JOIN。

0

錯誤的查詢,您通過在where子句中使用它們將一些左連接轉換爲內連接。您需要將tbl_product_seo和tbl_product_details的過濾條件移至左連接的ON子句。

0

正如HLGEM所說,左邊的連接在其中一些表上沒有意義,只要您在where子句中使用它們,Optimizer就會將它們轉換爲INNER JOINS。

原因是您通常使用LEFT JOIN獲取一個表中的記錄以及任何記錄(如果它們存在於第二個表中),這會返回NULLS,其中第二個表中不存在任何記錄。

與使用WHERE子句限制在第二個表項,它永遠不能返回空值,因此一個LEFT JOINS是毫無意義的

相關問題