【问题标题】:Finding a solution to making a MYSQL JOIN work with relational tables and a global variable寻找使 MYSQL JOIN 与关系表和全局变量一起工作的解决方案
【发布时间】:2026-01-20 03:25:01
【问题描述】:

编辑:以下代码显示了问题的答案。感谢 VolkerK。

$result = mysqli_query($link,"SELECT ctas.*, ctas_pr.*, nav.id
                              FROM web_ctas AS ctas

                              LEFT JOIN web_ctas_page_relation AS ctas_pr
                              ON ctas.id = ctas_pr.cta_id

                              LEFT JOIN web_navbar  AS nav
                              ON ctas_pr.navbar_id = nav.id
                              AND nav.link_name = '".$page."'")

                              or die(mysqli_error($link)
                      );

早上好/下午/晚上,

我希望你们中的一些人可以帮助我解决有关 mySQL 的特定问题。

我正在尝试JOIN 两个表传递一些逻辑并取回匹配的相关字段数据,我必须解释过程和表,以便您对代码和过程有一点了解。

“web_ctas”表有一个与 web_navbar 表对应的关系字段。

非常感谢任何可以在此问题上提供帮助的人。

下面是两张表:

web_ctas

id | title | img_src | img_alt | link_href | link_title | desc
==============================================================
1  | title | pears   | apples  | foo       | bar        | blah
2  | title | apples  | pears   | bar       | foo        | bleh

web_navbar

id | link_name | visible
========================
1  | home      |   1
2  | products  |   1

web_ctas_page_relation

id | cta_id | navbar_id
=======================
1  |    1   |    2
2  |    2   |    2

以下是我到目前为止的 SQL(我知道这可能根本行不通):

$query = mysqli_query($link,"SELECT web_ctas.*, web_navbar.id AS nav_id
                             FROM web_ctas
                             JOIN web_navbar
                             ON web_navbar.id = web_ctas.page_relation
                             AND page_relation='".$page."'");

下面是 HTML/PHP,它将从 SQL 查询结果中提取数据。

$page = 'home';

while($row = mysqli_fetch_object($query)): ?>
        <li>
            <a href="<? echo $row->link_href; ?>" title="<? echo $row->link_title; ?>">
                <h3><? echo $row->title; ?></h3>
                <div>
                    <img src="<? echo $row->img_src; ?>" alt"<? echo $row->img_alt; ?>">
                </div>
            </a>
        </li> <?
    endwhile;

因此,简而言之,我正在寻找一种方法,当 web_navbar 表与 web_ctas 中的一行匹配时,它可以从该表中获取 link_name 字段page_relation 字段中具有关系 id 并匹配变量 $page。

如果我遗漏了任何关键代码/信息,请告诉我。

【问题讨论】:

  • 为了使您的查询与 SQL 注入相比更加健壮,请使用 prepare statement 进行查询。
  • 没有用户可以输入数据以传递给数据库的形式,如果是这种情况,用户/黑客仍然可以将字符串传递给数据库吗?
  • 更改表格布局是否可能/可行?您当前的布局违反了第一范式。有(很好的)理由忽略数据库规范化;但您的问题似乎不属于该类别;-) 请参阅en.wikipedia.org/wiki/First_normal_form
  • 刚刚快速阅读,这很有意义,ty。如果我理解正确,我需要制作第三个表'web_ctas_page_relation',其中包含 id|cta_id|navbar_id ??
  • third table ... that contains id|cta_id|navbar_id - 正确

标签: php mysql join subquery


【解决方案1】:

对不起,该走了;仅是示例脚本的时间,而不是解释。既然你已经自己弄清楚了关系表,只给了 1NF 链接,我相信你也可以通过这个链接进行挖掘;-)
使用 mysqli 而不是 pdo_mysql 的工作方式相同。

<?php
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'localonly', 'localonly');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
setup($pdo);

$navbar = 'nav_36'; // this would be $navbar='products'; in your case
$stmt = $pdo->prepare('
    SELECT
        nv.id as navid,
        nv.link_name,
        ct.id as ctasid,
        ct.title,
        ct.link_href
    FROM 
        tmp_web_navbar as nv
    LEFT JOIN
        tmp_web_ctas_nav_rel as r
    ON
        nv.id = r.id_navbar
    LEFT JOIN
        tmp_web_ctas as ct
    ON
        r.id_ctas=ct.id
    WHERE
        nv.link_name = ?
');
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$stmt->execute(array($navbar));
foreach($stmt as $row ) {
    foreach($row as $k=>$v) {
        echo $k,'=', $v, ' ';
    }
    echo "\n";
}

// boilerplate for creating table layout and populating some example data
function setup($pdo) {
    $pdo->exec('
        CREATE TEMPORARY TABLE tmp_web_navbar (
            id int auto_increment,
            link_name varchar(32),
            visible varchar(32),
            primary key(id)
        )
    ');
    // add some entries to tmp_web_navbar since the example data uses the range [1,50]
    $stmt = $pdo->prepare('INSERT INTO tmp_web_navbar (link_name,visible) VALUES (?,?)');
    for($i=1; $i<60; $i++) {
        $stmt->execute(array(sprintf('nav_%02d', $i), 'title'));
    }

    $pdo->exec('
        CREATE TEMPORARY TABLE tmp_web_ctas (
            id int auto_increment,
            title varchar(32),
            link_href varchar(32),
            primary key(id)
        )
    ');
    // add some ctas elements
    $stmt = $pdo->prepare('INSERT INTO tmp_web_ctas (title,link_href) VALUES (?,?)');
    for($i=1; $i<60; $i++) {
        $stmt->execute(array('title', sprintf('ctas_%02d', $i)));
    }

    $pdo->exec("INSERT INTO tmp_web_ctas (title,link_href) VALUES
        ('title','foo'),
        ('title ','bar')
    ");

    // a table to store the relationships
    $pdo->exec('
        CREATE TEMPORARY TABLE tmp_web_ctas_nav_rel (
            id int auto_increment,
            id_ctas int,
            id_navbar int,
            primary key(id),
            key(id_ctas)
        )
    ');

    // and define some relationships
    // three of them having id_navbar=36: cats=4,5 and 7
    $stmt = $pdo->prepare('INSERT INTO tmp_web_ctas_nav_rel (id_ctas,id_navbar) VALUES (?,?)');
    $rel = array(
        1=>array(1,6,10,50),
        2=>array(2,13,15,30),
        3=>array(9,7,11,51),
        4=>array(17,24,36,34), // here
        5=>array(18,24,36,35), // here
        6=>array(19,24,33,38),
        7=>array(19,24,32,36), // and here
        8=>array(19,24,39,38),
    );
    foreach($rel as $ctas=>$navrels) {
        foreach( $navrels as $nav ) {
            $stmt->execute(array($ctas,$nav));
        }
    }
}

【讨论】:

  • 我昨晚也没有时间了,今天就看看这个,ty。
  • Danke VolerK 感谢您的帮助,我终于使用您的 post 方法找到了解决方案。 :)
【解决方案2】:
$query = mysqli_query($link,"SELECT web_ctas.*, web_navbar.id AS nav_id
                             FROM web_ctas
                             JOIN web_navbar
                             ON web_navbar.id IN (web_ctas.page_relation)
                             AND page_relation='".$page."'");

【讨论】:

  • 除非我做错了什么;我完全复制了你的代码,这不起作用。
最近更新 更多