4

tb_content(左)とtb_word(右):

=====================================    ================================
|id|sentence |sentence_id|content_id|    |id|word|sentence_id|content_id|
=====================================    ================================
| 1|sentence1|    0      |    1     |    | 1|  a |     0     |    1     |
| 2|sentence2|    1      |    1     |    | 2|  b |     0     |    1     |
| 3|sentence5|    0      |    2     |    | 3|  c |     1     |    1     |
| 4|sentence6|    1      |    2     |    | 4|  a |     1     |    1     |
| 5|sentence7|    2      |    2     |    | 5|  e |     1     |    1     |
=====================================    | 6|  f |     0     |    2     |
                                         | 7|  g |     1     |    2     |
                                         | 8|  h |     1     |    2     |
                                         | 9|  i |     1     |    2     |
                                         |10|  f |     2     |    2     |
                                         |11|  h |     2     |    2     |
                                         |12|  f |     2     |    2     |
                                         ================================

すべての文が、すべての他の文が所有する単語で構成されているかどうかを確認する必要がありますcontent_id

例えば ​​:

content_id=1それらがsentence1とであるかどうかを確認しsentence2ます。からtb_word、それを見ることができ、同じ単語sentence1で構成されています。2文の数が、の場合、結果になります。したがって、結果を出力する場合は、次のようにする必要があります。 ここで、means =および=sentence2aa>=2a00Array ( [0] => a [1] => b) 01Array ( [3] => a ) 10Array ( [3] => a )11Array ( [0] => c [1] => a [2] => e)00sentence_id0sentence_id0

まず、すべての人が所有しているもの functionTotalの数を数えます:sentencecontent_id

$total = array();
$sql = mysql_query('select content_id, count(*) as RowAmount 
       from tb_content Group By contente_id') or die(mysql_error());
while ($row = mysql_fetch_array($sql)) {
    $total[] = $row['RowAmount']; 
}
return $total;

その関数から私はの値を取得し、そこから2のすべての可能性の間$totalのいくつかの単語(から)の類似性をチェックする必要がありますtb_wordsentence

foreach ($total as $content_id => $totals){
for ($x=0; $x <= ($totals-1); $x++) {
    for ($y=0; $y <= ($totals-1); $y++) {
      $shared = getShared($x, $y);
    }
}

の機能getSharedは:

function getShared ($x, $y){
    $token = array();
    $shared = array();
    $i = 0;
    if ($x == $y) {
        $query = mysql_query("SELECT word FROM `tb_word`
                             WHERE sentence_id ='$x' ");
        while ($row = mysql_fetch_array($query)) {
            $shared[$i] = $row['word'];
            $i++;
        }

    } else {
        $query = mysql_query("SELECT word, count(word) as jml 
                             FROM `tb_word` WHERE sentence_id ='$x' 
                             OR sentence_id ='$y' 
                             GROUP BY word ");
        while ($row = mysql_fetch_array($query)) {
            $jml = $row['jml'];
            $token[$i] = $row['word'];
            if ($jml >= 2) {
                $shared[$i] = $token[$i];
            }
            $i++;
        }

しかし、私が得る結果はまだ間違っています。結果はまだ異なる間で混合されますcontent_id。結果もgroupbyである必要がありますcontent_id。私の悪い英語と私の悪い説明でごめんなさい。cmiiw、助けてください..ありがとう:)

4

2 に答える 2

1

簡単にSELECT content_id, word, COUNT(*) as num_appearing FROM tb_word GROUP BY content_id, wordいかがですか?

編集:私は今複雑さを理解しています:あなたの主な問題は、getShared()関数に2つの文IDが渡されているが、content_idどのコンテンツが分析されているかわからないことです。content_idまた、とsentence_idの数字は連続していて、ゼロから始まると仮定しています。私のコードはそれを想定しておらず、データベースから直接それらのIDを取得します。

<?php
$rs = mysql_query("SELECT * FROM tb_content");
$content = array();
while ($row = mysql_fetch_assoc($rs)) {
    if (!isset($content[$row['content_id']])) $content[$row['content_id']] = array();
    $content[$row['content_id']][] = $row['sentence_id'];
}
foreach($content as $content_id => $sentences) {
  foreach($sentences as $sentence_id) {
    foreach($sentences as $compare) {
      $shared = getShared($content_id, $sentence_id, $compare);
    }
  }
}
function getShared($cid, $s1, $s2) {
  $rs = mysql_query("SELECT `word`, COUNT(*) AS 'num' FROM `tb_word` WHERE `content_id`={$cid} AND `sentence_id` IN ({$s1}, {$s2}) GROUP BY `word`");
  $out = array();
  while ($row = mysql_fetch_assoc($rs)) {
    if ($rs['num'] >= 2) $out[$rs['word']] = $rs['num'];
  }
  return $out;
}
于 2012-09-14T05:02:33.573 に答える
1

これは実際にはDBMS自体で実行でき、1つのクエリで2つのステップを実行します。まず、同じコンテンツ内で文の組み合わせを準備するために、自己結合を行います。

SELECT a.content_id,
       a.sentence_id AS sentence_id_1,
       b.sentence_id AS sentence_id_2
FROM   tb_content AS a
       JOIN tb_content AS b
         ON ( a.content_id = b.content_id
              AND a.sentence_id <= b.sentence_id )

「<=」は、「1-1」や「2-2」のように同じ文の結合を維持しますが、「1-2」や「2-1」のように双方向の繰り返しを避けます。次に、上記の結果を単語と結合して、出現回数を数えることができます。そのように:

SELECT s.content_id,
       s.sentence_id_1,
       s.sentence_id_2,
       c.word,
       Count(*) AS jml
FROM   (SELECT a.content_id,
               a.sentence_id AS sentence_id_1,
               b.sentence_id AS sentence_id_2
        FROM   tb_content AS a
               JOIN tb_content AS b
                 ON ( a.content_id = b.content_id
                      AND a.sentence_id <= b.sentence_id )) AS s
       JOIN tb_word AS c
         ON ( s.content_id = c.content_id
              AND ( c.sentence_id = s.sentence_id_1
                     OR c.sentence_id = s.sentence_id_2 ) )
GROUP  BY s.content_id,
          s.sentence_id_1,
          s.sentence_id_2,
          c.word
HAVING Count(*) >= 2; 

上記のクエリの結果は、コンテナ、文1と2、単語、および出現回数(2以上)を示します。今必要なのは、結果を配列に収集することだけです。これは、私が見ているように、すでに知っていることです。

私があなたの目標を誤解した場合は、私に知らせてください。

于 2012-09-14T22:34:55.823 に答える