【问题标题】:Which JOIN to use使用哪个 JOIN
【发布时间】:2013-11-14 12:45:52
【问题描述】:

我正在尝试从表格中获取信息。

我有板子和子板子。表board 中的sub_id 列告诉我板子是否是子板。如果是子板则父板的id为值,如果不是则单元格为空。

我写这个是为了显示一个板是否有任何子板:

<?php 
$data = mysql_query("SELECT * FROM board WHERE sub_id='$boardId'") 
or die(mysql_error()); 
while($info = mysql_fetch_array( $data )) 
{ 
Print "<br>Sub-collections:<br>";
Print "<font size='5pt'><a href='/board/index/".$info['id']."'>".$info['board_name']."    </a></font>";
} 
?>

这很好用。

现在我想编写一个类似的代码来命名父板(如果板是子板),但这是我遇到问题的地方。

我想出了:

<?php 
$data = mysql_query("select * from board WHERE id='$boardId' AND sub_id IS NOT NULL")     or die(mysql_error());
$issub = mysql_fetch_array($data);
?>

然后使用...

<?php if(($issub)): ?>
<?php echo $issub['sub_id'] ?>
<?php else: ?>
<?php endif ?>

显示。

问题在于没有join,除了母板的id,我无法显示任何内容。我不知道要加入哪些列才能提取board_name 等信息。

编辑:

popovitsj 的建议:

<?php 
$data = mysql_query("SELECT * FROM board b WHERE EXISTS(SELECT * FROM board WHERE b.id     = sub_id)") or die(mysql_error()); 
while($info = mysql_fetch_array( $data )) 
{ 
Print "<br>Sub-collection of:<br>";
Print "<font size='5pt'><a href='/board/index/".$info['id']."'>".$info['board_name']."    </a></font>";
} 
?>

这在一定程度上有效。在子板页面上正确显示父板,但在父板页面上也错误显示。

EDIT2:

根据 Meier 的建议研究 LEFT JOIN 后,我最终使用以下代码使其工作:

SELECT * FROM board a LEFT JOIN board b ON a.sub_id = b.id WHERE a.sub_id LIKE b.id AND a.id='$boardId'

【问题讨论】:

  • 有点混乱,您称列引用父子板。你应该把它叫做 parent_board。
  • 很难理解您的表格是什么样的。你能说清楚一点吗?
  • 不是。这是sub_id。我希望能够在尽可能少的列中做到这一点。
  • 只有一张桌子 = board。其中包含有关用户创建的板的信息:idboard_nameuser_iddescriptiontime_created。我添加了一个新列:sub_id。这使用户能够将一个板指定给另一个板。例如,如果他们选择将 ID 为 56102 的板链接在一起作为 56 的子板 102。在板 102 的列 sub_id 中,值将是 56。这告诉我板 102 是板 56 的子板。板 56 的数据没有任何改变。我只是使用 sql 检查它的id 是否被用作sub_id
  • 是的,这令人困惑。想一想,sub_id 指的是什么?它是指 sub_board 吗?不,它指的是 sub_board 的父级。

标签: php sql join


【解决方案1】:

在我回答问题之前:您是否 100% 确定 $boardid 不是直接来自 http,因此可以被用户操作,因此您的用户无法启动 sql 注入?

您需要的联接是“外部自联接”。外部联接,因为您还想显示没有父级的板。外连接也称为左连接。 自连接,因为表连接到自身。自连接的诀窍是在语句中为表赋予不同的名称,以便您可以区分父级和子级。

在谷歌上快速搜索“sql external self join”给了我这个,这很好地解释了它。 以员工和经理为例,经理也是员工。所以这个例子和你的很相似: http://blog.sqlauthority.com/2010/07/08/sql-server-the-self-join-inner-join-and-outer-join/

【讨论】:

  • 尝试了这个没有运气:选择 * from board a left join board b on a.id = b.sub_id WHERE b.sub_id LIKE $boardId 任何建议,它仍然调用子板,而不是父母.我要做什么?
  • 我摆弄它并让它工作:SELECT * FROM board a LEFT JOIN board b ON a.sub_id = b.id WHERE a.sub_id LIKE b.id AND a.id='$ boardId'
【解决方案2】:

对此有不同的解决方案。一种可能的情况是:

SELECT * FROM Board b
WHERE EXISTS
   (SELECT * FROM Board
    WHERE b.id = sub_id);

另一个可能的解决方案可能是这样,这仅显示“根”父板。 (没有父母的董事会)。

SELECT * FROM Board b
WHERE sub_id IS NULL;

【讨论】:

  • 这在一定程度上有效:子集合:
    ”;打印 "".$info['board_name']." 字体>"; } ?> 在子板页面上,它正确识别了父板。但在母版页面上,它还显示“...的子集合”并列出了自己。
  • 这个查询只获取所有父母。如果您想要某个父项的所有子项,请使用不同的查询。
猜你喜欢
  • 2011-08-09
  • 1970-01-01
  • 2021-07-10
  • 2022-01-20
  • 2017-11-30
  • 2010-11-08
  • 1970-01-01
  • 2014-03-13
  • 2016-09-15
相关资源
最近更新 更多