PHP / MySQL:编写SELECT查询的更好方法是什么?

时间:2010-11-19 15:23:36

标签: php mysql

有没有更好的方法来编写此查询?

startimg point:index.php?IDGruppo = 25,48,47& IDFamiglia = 845,587,215,444

现在我爆炸IDGruppo和IDFamiglia并构建如下的查询:

有一种最好的方法吗?

$sql = "SELECT * FROM catalogo_prodotti cp, catalogo_prodotti_attributi cpa WHERE cp.IDProdotto = cpa.IDProdotto ";

if($IDGruppo || $IDVarianti){

    $sql .= "AND ";

    foreach($idg as $v)
    {

    if($IDVarianti){
        $i = 1;
        foreach($idv as $c)
        {
        $sql .= "cp.IDGruppo = '". $v ."' AND cp.IDFamiglia = '".$c."' AND cp.Cancellato = '0' AND cp.Acquistabile = '1' ";

        if($IDTaglia)
         $sql .= "AND cpa.IDFiltro_Taglia = '".$IDTaglia."' ";

        if($IDTessuto)
         $sql .= "AND cp.Key_IT LIKE '%".$IDTessuto."%' ";

        if ( count($idv) != $i ){
         $sql .= "OR ";

         }
        $i++;
        }

    } else {

    $sql .= "cp.IDGruppo = '". $v ."' AND cp.Cancellato = '0' AND cp.Acquistabile = '1' ";

    }
     if ( count($idg) != $j )
     $sql .= "OR ";
     $j++;
    }

}

$sql .= "GROUP BY cp.IDProdotto LIMIT $offset, ".$this->ipp." ";

if($orderBY)
$sql .= "ORDER BY '".$orderBY."'";

6 个答案:

答案 0 :(得分:4)

SELECT * 
FROM catalogo_prodotti cp
JOIN catalogo_prodotti_attributi cpa ON cp.IDProdotto = cpa.IDProdotto 
 AND cp.Acquistabile = '1' AND AND cp.Cancellato = '0'
WHERE
cp.IDGruppo = '33' AND cp.IDFamiglia = '121' 
OR cp.IDGruppo = '33' AND cp.IDFamiglia = '123'  
OR cp.IDGruppo = '33' AND cp.IDFamiglia = '159'
OR cp.IDGruppo = '33' AND cp.IDFamiglia = '179' 
OR cp.IDGruppo = '30' AND cp.IDFamiglia = '121'
OR cp.IDGruppo = '30' AND cp.IDFamiglia = '123'
OR cp.IDGruppo = '30' AND cp.IDFamiglia = '159' 
OR cp.IDGruppo = '30' AND cp.IDFamiglia = '179'
OR cp.IDGruppo = '29' AND cp.IDFamiglia = '121'
OR cp.IDGruppo = '29' AND cp.IDFamiglia = '123' 
OR cp.IDGruppo = '29' AND cp.IDFamiglia = '159'
OR cp.IDGruppo = '29' AND cp.IDFamiglia = '179'

GROUP BY cp.IDProdotto LIMIT 0, 40

或者可能:

编辑 - 添加括号

SELECT * 
FROM catalogo_prodotti cp
JOIN catalogo_prodotti_attributi cpa ON cp.IDProdotto = cpa.IDProdotto 
    AND cp.Acquistabile = '1' AND AND cp.Cancellato = '0'
WHERE
(cp.IDGruppo = '33' AND cp.IDFamiglia IN ('121','123','159','179'))
OR (cp.IDGruppo = '30' AND cp.IDFamiglia IN ('121','123','159','179'))
OR (cp.IDGruppo = '29' AND cp.IDFamiglia IN ('121','123','159','179'))

GROUP BY cp.IDProdotto LIMIT 0, 40

答案 1 :(得分:2)

这会将您的OR个条款替换为几个IN条款。

SELECT * FROM catalogo_prodotti cp, catalogo_prodotti_attributi cpa 
WHERE cp.IDProdotto = cpa.IDProdotto 
AND cp.IDGruppo IN (29, 30, 33) 
AND cp.IDFamiglia IN (121, 123, 159, 179)
AND cp.Cancellato = '0' 
AND cp.Acquistabile = '1' 
GROUP BY cp.IDProdotto LIMIT 0, 40

以下是使用IN的其他examples,此处是指向MySQL documentation for IN的链接。

来自文档:

  
      
  • expr IN (value,...)
      如果1等于expr列表中的任何值,则返回IN,否则返回0
  •   

答案 2 :(得分:0)

使用括号对子语句进行分组已经有所帮助。例如cp.Cancellato在同一个标​​题中出现12次,而不是仅出现一次。尝试为自己构建一个逻辑树,然后编写语句。

答案 3 :(得分:0)

使用一些括号,仅使用SELECT子句中出现在GROUP BY(或聚合函数)中的列,使用格式,并消除WHERE子句中的重复。

SELECT cp.IDProdotto
FROM catalogo_prodotti cp, catalogo_prodotti_attributi cpa 
WHERE cp.IDProdotto = cpa.IDProdotto 
AND cp.Cancellato = '0' 
AND cp.Acquistabile = '1' 
AND (
     (cp.IDGruppo = '33' AND cp.IDFamiglia = '121')
  OR (cp.IDGruppo = '33' AND cp.IDFamiglia = '123')
  OR (cp.IDGruppo = '33' AND cp.IDFamiglia = '159')
  OR (cp.IDGruppo = '33' AND cp.IDFamiglia = '179')
  OR (cp.IDGruppo = '30' AND cp.IDFamiglia = '121')
  OR (cp.IDGruppo = '30' AND cp.IDFamiglia = '123')
  OR (cp.IDGruppo = '30' AND cp.IDFamiglia = '159')
  OR (cp.IDGruppo = '30' AND cp.IDFamiglia = '179')
  OR (cp.IDGruppo = '29' AND cp.IDFamiglia = '121')
  OR (cp.IDGruppo = '29' AND cp.IDFamiglia = '123')
  OR (cp.IDGruppo = '29' AND cp.IDFamiglia = '159')
  OR (cp.IDGruppo = '29' AND cp.IDFamiglia = '179')
)
GROUP BY cp.IDProdotto 
LIMIT 0, 40

答案 4 :(得分:0)

SELECT * 
FROM catalogo_prodotti cp, catalogo_prodotti_attributi cpa 
WHERE cp.IDProdotto = cpa.IDProdotto
AND cp.Acquistabile = '1' 
AND cp.Cancellato = '0' 
AND cp.IDFamiglia IN('121','123','159','179')
AND cp.IDGruppo IN ('33','30','29')
GROUP BY cp.IDProdotto LIMIT 0, 40

答案 5 :(得分:0)

下面的查询似乎符合您的意图,但您应该重新考虑您要实现的目标。 MySQL允许您滥用GROUP BY语句并返回未分组或聚合的列。这意味着为这些列返回的特定值是不确定的,并且可能来自任何一个匹配的行。这就是你想要的吗?

SELECT *  
FROM catalogo_prodotti cp 
INNER JOIN catalogo_prodotti_attributi cpa ON cp.IDProdotto = cpa.IDProdotto  
WHERE cp.Acquistabile = '1' 
    AND cp.Cancellato = '0' 
    AND cp.IDGruppo in ('29', '30', '33')
    AND cp.IDFamiglia in ('121', '123', '159', '179')
GROUP BY cp.IDProdotto 
LIMIT 0, 40