嘿伙计们,我环顾四周,但没有解决这个问题。
我有一个帖子/评论数据库,我无法正确订购。
我需要它主要通过它的id来排序,但如果它的parent_id不等于它的id,它将被放置在它的父节点之后,这些子节点也会按id排序。
这是我目前的数据库。
CREATE TABLE `questions` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`parent_id` int(10) NOT NULL,
`entry_type` varchar(8) NOT NULL,
`entry_content` varchar(1024) NOT NULL,
`entry_poster_id` varchar(10) NOT NULL,
`entry_status` varchar(1) NOT NULL,
`entry_score` varchar(10) NOT NULL,
`time_posted` varchar(10) NOT NULL,
PRIMARY KEY (`id`),
KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;
--
-- Dumping data for table `questions`
--
INSERT INTO `questions` VALUES(1, 1, 'question', 'How do I does SQL?', 'CodyC', '0', '2', '1308641965');
INSERT INTO `questions` VALUES(2, 1, 'answer', 'Easy, you eat cheese!', 'PatrickS', '0', '-4', '1308641965');
INSERT INTO `questions` VALUES(3, 2, 'comment', 'WTF are you on noobass?!', 'FraserK', '0', '100', '1308641965');
INSERT INTO `questions` VALUES(4, 1, 'answer', 'blah', '5', '0', '0', '1308642204');
INSERT INTO `questions` VALUES(5, 4, 'comment', 'blah2', '4', '0', '0', '1308642247');
INSERT INTO `questions` VALUES(6, 2, '2', '3', '3', '3', '3', '3');
和我当前的查询
SELECT *
FROM questions
WHERE parent_id =1
OR parent_id
IN (
SELECT id
FROM questions
WHERE parent_id =1
AND parent_id != id
)
我如何订购,以便每个对象在其父级之后的订单ID,其中id = parent_id表示基础级别且没有父级!
提前致谢。
弗雷泽
答案 0 :(得分:1)
这似乎有效:
SELECT *
FROM questions
order by case when parent_id != id then parent_id else id end, id;
但这取决于你是否想要孩子之前的孙子等。你的问题没有说明。
但是,如果您使用这种技术,您可以根据需要使订购条款变得复杂 - 它不需要是选定的列 - 只需补充您需要的内容即可。
答案 1 :(得分:0)
使用mysql看起来有点复杂,但你可以使用PHP。使用递归函数。这很容易处理。
这是代码库中的一个函数。它只是创建一个无序列表树。您可以根据自己的要求对其进行修改
function output_lis_pages($parentID = 0)
{
$stack = array(); //create a stack for our <li>'s
$arr = array();
$sql = "select pageid, pagetitle, pagelink, parentid
from pages
where parentid = $parentID
order by orderid";
$crs = mysql_query($sql);
if(mysql_num_rows($crs)==0)
{
// no child menu exists for this page
return false;
}
else
{
while($crow = mysql_fetch_array($crs))
{
$arr [] = array(
'pagetitle'=> stripslashes($crow["pagetitle"]),
'pagelink'=> $crow["pagelink"],
'parentid'=>$crow["parentid"],
'pageid'=>$crow["pageid"]
);
}
}
foreach($arr as $a)
{
$str = '';
//if the item's parent matches the parentID we're outputting...
if($a['parentid']==$parentID)
{
if($a['pagelink']=="")
$tmplink = "page.php?pageid=".$a['pageid'];
else
$tmplink = $a['pagelink'];
$str.='<li><a href="'.$tmplink.'">'.$a['pagetitle']."</a>";
$subStr = output_lis_pages($a['pageid']);
if($subStr){
$str.="\n".'<ul>'.$subStr.'</ul>'."\n";
}
$str.='</li>'."\n";
$stack[] = $str;
}
}
//If we have <li>'s return a string
if(count($stack)>0)
{
return join("\n",$stack);
}
//If no <li>'s in the stack, return false
return false;
}
答案 2 :(得分:0)
SELECT *
, CASE WHEN parent_id = 1 THEN id ELSE parent_id END AS sort_level
FROM questions
WHERE parent_id = 1
OR parent_id
IN (
SELECT id
FROM questions
WHERE parent_id = 1
AND parent_id != id
)
ORDER BY sort_level
, id
答案 3 :(得分:0)
你遇到了关系数据库系统的旧bugbear。当您的数据具有层次结构时,使用它们并不好玩。您有尝试从数据库记录中生成图表的特定步骤的问题。没有SQL方言中的递归功能,这很难实现。这是一个可能有用的链接: http://explainextended.com/2009/03/17/hierarchical-queries-in-mysql/
另请参阅StackOverflow:What are the options for storing hierarchical data in a relational database?
答案 4 :(得分:0)
调查你的问题并阅读你的评论 - “我需要得到一个具体问题,包括所有答案和评论”,我认为你希望展示每个问题,然后是答案,然后是评论。正确?
如果是这样,这是您的查询:
SELECT `id`,
(CASE
WHEN `entry_type` = 'question' THEN CONCAT(`id`, '-', `parent_id`)
WHEN `entry_type` = 'answer' THEN CONCAT(`id`, '-', `parent_id`)
WHEN `entry_type` = 'comment' THEN CONCAT(`parent_id`, '-', `id`)
END) `sort_order`,
`entry_type`, `entry_content`
FROM `questions`
ORDER BY `sort_order`;
以上查询将为您提供每个问题,然后是第一个答案,然后是对第一个答案的评论;然后是第二个答案,然后是对第二个答案的评论,依此类推。
因此,对于您给出的INSERT,这将是输出:
+----+------------+------------+--------------------------+
| id | sort_order | entry_type | entry_content |
+----+------------+------------+--------------------------+
| 1 | 1-1 | question | How do I does SQL? |
| 2 | 2-1 | answer | Easy, you eat cheese! |
| 3 | 2-3 | comment | WTF are you on noobass?! |
| 6 | 2-6 | comment | 3 |
| 4 | 4-1 | answer | blah |
| 5 | 4-5 | comment | blah2 |
+----+------------+------------+--------------------------+
希望它有所帮助。
编辑:更新了查询,仅针对一个问题获取答案和评论
SELECT `id`,
(CASE
WHEN (`entry_type` IN ('question', 'answer')) THEN `id`
WHEN `entry_type` = 'comment' THEN `parent_id`
END) `sort_order_1`,
(CASE
WHEN (`entry_type` IN ('question', 'answer')) THEN `parent_id`
WHEN `entry_type` = 'comment' THEN `id`
END) `sort_order_2`,
(CASE
WHEN (`entry_type` IN ('question', 'answer')) THEN `parent_id`
WHEN `entry_type` = 'comment' THEN (SELECT `Q1`.`parent_id` FROM `questions` `Q1` WHERE `Q1`.`id` = `Q`.`parent_id`)
END) `question_id`,
`entry_type`, `entry_content`
FROM `questions` `Q`
HAVING `question_id` = 1
ORDER BY `sort_order_1`, `sort_order_2`;
输出:
+----+--------------+--------------+-------------+------------+--------------------------+
| id | sort_order_1 | sort_order_2 | question_id | entry_type | entry_content |
+----+--------------+--------------+-------------+------------+--------------------------+
| 1 | 1 | 1 | 1 | question | How do I does SQL? |
| 2 | 2 | 1 | 1 | answer | Easy, you eat cheese! |
| 3 | 2 | 3 | 1 | comment | WTF are you on noobass?! |
| 6 | 2 | 6 | 1 | comment | 3 |
| 4 | 4 | 1 | 1 | answer | blah |
| 5 | 4 | 5 | 1 | comment | blah2 |
+----+--------------+--------------+-------------+------------+--------------------------+
您可以更改HAVING部分以获取特定问题的答案和评论。希望这有帮助!
编辑2 :可能是另一种可能的实现(但我认为它可能对大型表有一些性能影响):
SELECT `a`.`id` AS `question_id`, `a`.`entry_content` AS `question`,
`b`.`id` AS `answer_id`, `b`.`entry_content` AS `answer`,
`c`.`id` AS `comment_id`, `c`.`entry_content` AS `comment`
FROM `questions` `a`
LEFT JOIN `questions` `b` ON (`a`.`id` = `b`.`parent_id` AND `b`.`entry_type` = 'answer')
LEFT JOIN `questions` `c` ON (`b`.`id` = `c`.`parent_id` AND `c`.`entry_type` = 'comment')
WHERE `a`.`entry_type` = 'question'
AND `a`.`id` = 1
ORDER BY `a`.`id`, `b`.`id`, `c`.`id`;
输出:
+----+--------------------+------+-----------------------+------+--------------------------+
| id | question | id | answer | id | comment |
+----+--------------------+------+-----------------------+------+--------------------------+
| 1 | How do I does SQL? | 2 | Easy, you eat cheese! | 3 | WTF are you on noobass?! |
| 1 | How do I does SQL? | 2 | Easy, you eat cheese! | 6 | 3 |
| 1 | How do I does SQL? | 4 | blah | 5 | blah2 |
+----+--------------------+------+-----------------------+------+--------------------------+
答案 5 :(得分:0)
经过一周的尝试后,我无法让它与查询一起工作,所以我决定只在PHP中执行它,这也将减少MySQL引擎的负载。这是我希望引用它的任何人的PHP。
$question_id = $database->escape_string($question_id); //escape input
$q = "SELECT * FROM questions WHERE parent_id = $question_id OR parent_id IN (SELECT id FROM questions WHERE parent_id = $question_id AND parent_id != id) ORDER BY parent_id , id";
$database->dbquery($q);//query the DB
while($row = $database->result->fetch_assoc()){//Process results to standard array.
//other irrelevant stuff happens here
$unsorted[] = $row;
}
$question = array_shift($unsorted);//take the question off the array
$sorted[] = $question;//add it to the start of the sorted array
$qusetion_id = $question['id'];
foreach($unsorted as $row){//this creates a multidimensional hierarchy of the answers->comments
if($row['parent_id'] == $question_id){//if its an answer
$sorted_multi[$row['id']] = array();//create a new answer sub-array
$sorted_multi[$row['id']][] = $row;//append it
}else{
$sorted_multi[$row['parent_id']][] = $row;//append the answer to the correct sub-array
}
}
foreach($sorted_multi as $temp){//converts the multidimensional into a single dimension appending it to the sorted array.
foreach($temp as $row){
$sorted[] = $row;
}
}
单调乏味,但最终因为其他无法预料的处理需要在mysql之后完成而更好。
感谢所有回复:):)):)
答案 6 :(得分:-1)
Simply use the "ORDER BY" clause to select the ordering you want!
SELECT *
FROM questions
WHERE parent_id =1
OR parent_id
IN (
SELECT id
FROM questions
WHERE parent_id =1
AND parent_id != id
)
ORDER BY Parent_id , id