5

類推の簡単な表を作成しました。

+----+-------+-------+
| id | sku_1 | sku_2 |
+----+-------+-------+
|  1 | a1    | abcd  |
|  2 | a2    | a3    |
|  3 | a3    | a1    |
+----+-------+-------+
3 rows in set (0.00 sec)

それはどういう意味ですか?abcdこれは、記事付きの製品には記事付きの類似物があることを意味しますa1。そうでない場合、記事付きの製品には記事a3付きの類似物がありますa1

単一の記事でこのテーブルからすべての製品を再帰的に取得する方法は?

私の解決策は間違っています:

// Small Class to get analogs of products
class Analogs {

    public function get_analogs($sku)
    {
        if (!$sku) return false;

        $link = mysql_connect('localhost','','');
        mysql_select_db('test');

        $sku = mysql_real_escape_string($sku,$link);

        $query = mysql_query("SELECT * FROM analogs WHERE sku_1='".$sku."' OR sku_2='".$sku."'");

        while($analogs[]=mysql_fetch_assoc($query))
        continue;

        return $analogs;    
    }


    public function MixedAnalogs($sku)
    {
        if (!$sku) return false;

        $link = mysql_connect('localhost','','');
        mysql_select_db('test');

        $sku = mysql_real_escape_string($sku,$link);

        $query = mysql_query("select sku_1 sku from analogs where sku_2 = '$sku' UNION
                              select sku_2 sku from analogs where sku_1 = '$sku'");

        while($analogs[]=mysql_fetch_assoc($query))
        continue;

        return $analogs;
    } 


}

$mixed_analogs = AnalogsMix('abcd',$ids=array());

echo "<pre>";
print_r($mixed_analogs);
echo "</pre>";

// Recursive function to get analogs of analog
function AnalogsMix($sku,$ids=array())
{
    $class_analogs = new Analogs();
    $analogs = $class_analogs->get_analogs($sku);

    foreach ($analogs as $analog)
    {
        $cross = null;

        if ($analog['sku_1']==$sku)
        {
            $cross->sku = $analog['sku_2'];
        }
        else
        {
            $cross->sku = $analog['sku_1'];
        }

        $cross->id = $analog['id'];

        if (!in_array($analog['id'],$ids))
        {
            $ids[] = $analog['id'];
            $mixed[] = AnalogsMix($cross->sku,$ids);
        }
    }

    if (isset($mixed))
    {
        return $mixed;
    }
    else
    {
        return false;
    }
}
4

3 に答える 3

1

SQL ユニオン

select sku_1 sku from analogs where sku_2 = $yourid
union
select sku_2 sku from analogs where sku_1 = $yourid

次に、類似体の ID のみを結果として取得します。

于 2013-03-25T14:39:00.807 に答える
1

ここで、配列にすべてのペアがあるとします。たとえば、あなたの例では、 を呼び出しますanalogsOf(array(array("a1", "abcd"), array("a2", "a3"), array("a3", "a1")), "abcd")

最初は探している文字列のみを含む類縁体のリストを作成し、類縁体を見つけるたびにそれを類縁体のリストに追加して繰り返すという考え方です。新しいものを見つけることなく、ペアの配列全体を反復するまでそうします。

function analogsOf(array $pairs, $key) {
    $res = array($key); // The result, with only the given key
    $i = 0;             // Index of the current item
    $changed = false;   // Have we added an item to $res during that iteration ?

    while ($i < count($pairs)) {
        $current = $pairs[$i];

        foreach ($res as $item) {
            if (($current[0] === $item) && (!in_array($current[1], $res)) {
                $res[] = $current[1];
                $i = 0;  // Reiterate as $res changed
            }
            else if (($current[1] === $item) && (!in_array($current[0], $res)) {
                $res[] = $current[0];
                $i = 0; // Reiterate as $res changed
            }
            else {
                $i++;  // Nothing found here, go to next item
            }
        }
    }

    return $res;
}

このコードはテストされていないことに注意してください。そのため、あちこちにいくつかのバグがある可能性がありますが、アイデアはあります。また、データベースのコンテンツ全体を配列に入れることができると考えていましたが、明らかな理由でおそらく不可能であるため、上記のコードを変更する必要があることに注意してください。

于 2013-03-25T15:01:06.413 に答える
1

この問題の解決策を見つけましたが、このアプローチの主な問題はそれです。のようなループを作ることができますabcd->a1,a1->a3,a3->a2,a2->abcd。再帰関数が無限になり、phpがエラーをスローします。そのため、それが大きなプロジェクトである場合は、それを確認する必要があります。

私の解決策では、親子関係と見なします。子が見つかった場合は、それを親にして、結果がなくなるまで再度チェックします。

letabcdは親で、最初の実行後a1は子であり、リレーションはabcd->a1です。しかし、次の呼び出し a1では親であり、テーブルの最初の行から新しい関係が与えられ、a1->abcd ループは無限です。同じ行のチェックを防ぐためにID、データベースの最後の行を使用し、id != ID の行をチェックします (常に他の行をチェックします)

これは私が書いた関数で、クラスに従って変換し、好きなように値を配列に格納します。糸のみを使用しています。私はそれが良い解決策ではないことを知っていましたが、うまくいきました。

<?php 

mysql_connect('localhost','','');
mysql_select_db('test');

function getSku($sku, $id, $rel = '') {
    $query = mysql_query("SELECT * FROM analogs WHERE sku_1 = '$sku' AND id != '$id'" );
    if (mysql_num_rows($query)) {
        $row = mysql_fetch_assoc($query);
        $sku = $row['sku_2']; //PARENT SKU
        $id = $row['id']; //LAST ID
        $rel .= $row['sku_1']. '-->' . $row['sku_2']. "<br>";

    } else {
        $query = mysql_query("SELECT * FROM analogs WHERE sku_2 = '$sku' AND id != '$id'" );
        if (mysql_num_rows($query)) {
            $row = mysql_fetch_assoc($query);
            $sku = $row['sku_1']; //PARENT SKU
            $id = $row['id']; //LAST ID
            $rel .=$row['sku_2']. '-->' . $row['sku_1']. '<br>';
        } else {

            return (string)$rel; //NOTHING FOUND
        }
    }
    return getSku($sku,$id,$rel);    

}

echo $new = getSku('abcd','-1');
于 2013-03-25T16:34:05.637 に答える