Sql多链表

时间:2011-03-04 02:16:27

标签: php sql linked-list iteration

我正在尝试显示可以采取某些步骤的顺序。某些步骤可以同时进行,而其他步骤则必须按特定顺序进行。我已将数据放在SQL表中,只是希望能够将其拉入PHP数组或其他内容,以便将其打印出来。

数据存储在1个sql表中,包含2个字段。第一个是stat(这个块的编号),第二个是prereq,它标识了前一个(这将是其他一些stat)。如果prereq字段为null,则这是起点。结束点是没有其他行的时候。

第一个例子:

status_number    prereq
-------------    -------
3                NULL
4                3
5                4
6                4
7                5
7                6
8                7

概念上看起来像这样:

我想在视觉上打印这个,首先我想把数据放到一个PHP数组中,使用嵌套数组,我将垂直拥有2个统计数据(在本例中为5& 6)。因此,数组看起来像:(3,4,(5,6),7,8)。如何将数据输入此表单?谢谢你的帮助!

2 个答案:

答案 0 :(得分:0)

在这里,你可能需要一些调整

/* fetch the status_numbers and prereqs */
$query = "SELECT status_number, prereq FROM status";
$rs = mysqli_query($dbc, $query);
while ($row = mysqli_fetch_row($rs)) {
    $ids[] = $row[0];
    $fwd[$row[0]][] = $row[1];
}

/* find the endpoint(s) */
$ends = array();
foreach ($ids as $search) {
    $found = false;
    foreach ($fwd as $deps) {
        if (in_array($search, $deps)) {
            $found = true;
            break;
        }
    }
    if ($found)
        continue;
    $ends[] = $search;
}

/* sort the deps so we can string compare */
foreach ($fwd as &$deps)
    asort($deps);

    /* recursive resolve function */
function resolve($fwd, $id, &$output) {
    if (!is_null($id))
        array_unshift($output, $id);

    $count = count($fwd[$id]);
    if ($count == 0)
        return;

    if ($count > 1) {
        $subs = array();
        $groups = array();
        foreach ($fwd[$id] as $dep)
            $subs[$dep] = implode(',', $fwd[$dep]);

        foreach ($subs as $dep => $str1) {
            unset($subs[$index]);
            foreach ($subs as $index => $str2)
                if ($str1 == $str2) {
                    unset($subs[$index]);
                    $groups[$str1][] = $index;
                }
        }

        foreach ($groups as $ids => $group) {
            array_unshift($output, $group);
            $ids = explode(',', $ids);
            foreach ($ids as $id)
                resolve($fwd, $id, $output);
        }
    }
    else {
        resolve($fwd, $fwd[$id][0], $output);
    }
}

$output = array();
foreach ($ends as $end)
    resolve($fwd, $end, $output);
print_r($output);

输出:

Array
(
  [0] => 3
  [1] => 4
  [2] => Array
      (
          [0] => 5
          [1] => 6
      )

  [3] => 7
  [4] => 8
)

答案 1 :(得分:0)

我认为这应该有效,但我必须承认我没有测试过它:

# get the data - let the DB handle the ordering
$sql = "SELECT status_number,prereq FROM t ORDER BY prereq, status_number"
$res = mysql_query($sql);

# initialize pre-loop stuff
$status_array = array();
$prev_prereq = '';

# loop through the results
while ($row = mysql_fetch_assoc($res))
{
  # check if the prereq is the same as the previous result, and if so...
  if ($prev_prereq == $row['prereq'])
  {
    # look at the last element in the array
    end($status_array);
    $lastIndex = key($status_array);

    # if it's not an array
    if (! is_array($status_array[lastIndex]))
    {
      #  make it one that contains the value that was in that spot
      $v = $status_array[lastIndex]
      $status_array[lastIndex] = array();
      status_array[$lastIndex][] = $v;
    }

    # then append the status to that array
    status_array[$lastIndex][] = $row['status_number'];

  } else
  # just append the latest status the the end of the status array
  {
    $status_array[] = $row['status_number'];
    $prev_prereq = $row['prereq'];
  }
}