Mysql 查询帮助 - 更改此 mysql 查询以获得这些结果?

发布于 2024-09-03 03:16:52 字数 3616 浏览 2 评论 0原文

请先执行以下查询进行设置,以便您可以帮助我:-

CREATE TABLE IF NOT EXISTS `Tutor_Details` (
`id_tutor` int(10) NOT NULL auto_increment,
`firstname` varchar(100) NOT NULL default '',
`surname` varchar(155) NOT NULL default '',
PRIMARY KEY (`id_tutor`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=41 ;

INSERT INTO `Tutor_Details` (`id_tutor`,`firstname`, `surname`) VALUES
(1, 'Sandeepan', 'Nath'),
(2, 'Bob', 'Cratchit');   

CREATE TABLE IF NOT EXISTS `Classes` (
`id_class` int(10) unsigned NOT NULL auto_increment,
`id_tutor` int(10) unsigned NOT NULL default '0',
`class_name` varchar(255) default NULL,
PRIMARY KEY (`id_class`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=229 ;

INSERT INTO `Classes` (`id_class`,`class_name`, `id_tutor`) VALUES
(1, 'My Class', 1),
(2, 'Sandeepan Class', 2);

CREATE TABLE IF NOT EXISTS `Tags` (
`id_tag` int(10) unsigned NOT NULL auto_increment,
`tag` varchar(255) default NULL,
PRIMARY KEY (`id_tag`),
UNIQUE KEY `tag` (`tag`),
KEY `id_tag` (`id_tag`),
KEY `tag_2` (`tag`),
KEY `tag_3` (`tag`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=18 ;

INSERT INTO `Tags` (`id_tag`, `tag`) VALUES
(1, 'Bob'),
(6, 'Class'),
(2, 'Cratchit'),
(4, 'Nath'),
(3, 'Sandeepan'),
(5, 'My');

CREATE TABLE IF NOT EXISTS `Tutors_Tag_Relations` (
`id_tag` int(10) unsigned NOT NULL default '0',
`id_tutor` int(10) default NULL,
KEY `Tutors_Tag_Relations` (`id_tag`),
KEY `id_tutor` (`id_tutor`),
KEY `id_tag` (`id_tag`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `Tutors_Tag_Relations` (`id_tag`, `id_tutor`) VALUES
(3, 1),
(4, 1),
(1, 2),
(2, 2);

CREATE TABLE IF NOT EXISTS `Class_Tag_Relations` (
`id_tag` int(10) unsigned NOT NULL default '0',
`id_class` int(10) default NULL,
`id_tutor` int(10) NOT NULL,
KEY `Class_Tag_Relations` (`id_tag`),
KEY `id_class` (`id_class`),
KEY `id_tag` (`id_tag`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `Class_Tag_Relations` (`id_tag`, `id_class`, `id_tutor`) VALUES
(5, 1, 1),
(6, 1, 1),
(3, 2, 2),
(6, 2, 2);
  • 在我提供的当前系统数据中,名为“Sandeepan Nath”的导师创建了名为“My Class”的班级,名为“Bob Cratchit”的导师创建了创建了名为“Sandeepan Class”的类。

要求 -

要执行对结果进行限制的单个查询,以按照搜索关键字的 AND 逻辑显示搜索结果,如下所示: -

  1. 如果搜索“Sandeepan Class”,则返回导师详细信息表中导师 Sandeepan Nath 的记录(因为“Sandeepan Class”) " 是 Sandeepan Nath 的名字,Class 出现在 Sandeepan 班级的班级名称中)
  2. 如果搜索“Class”,则会从 Tutor_details 表中获取两个导师,因为 Class 出现在两位导师创建的班级名称中。

以下是我迄今为止所取得的成就(PHP Mysql):-

<?php
$searchTerm1 = "Sandeepan";
$searchTerm2 = "Class";

mysql_select_db("test");


$sql = "SELECT td.*
FROM Tutor_Details AS td
LEFT JOIN Tutors_Tag_Relations AS ttagrels ON td.id_tutor = ttagrels.id_tutor
LEFT JOIN Classes AS wc ON td.id_tutor = wc.id_tutor
LEFT JOIN Class_Tag_Relations AS wtagrels ON td.id_tutor = wtagrels.id_tutor

LEFT JOIN Tags as t1 on ((t1.id_tag = ttagrels.id_tag) OR (t1.id_tag = wtagrels.id_tag))
LEFT JOIN Tags as t2 on ((t2.id_tag = ttagrels.id_tag) OR (t2.id_tag = wtagrels.id_tag))


where t1.tag LIKE '%".$searchTerm1."%'
AND t2.tag LIKE '%".$searchTerm2."%'

GROUP BY td.id_tutor
LIMIT 10
";

$result = mysql_query($sql);
echo $sql;
if($result)
{

while($rec = mysql_fetch_object($result)) $recs[] = $rec;
//$rec = mysql_fetch_object($result);
echo "<br><br>";

if(is_array($recs))
{
foreach($recs as $each)
{
print_r($each);
echo "<br>";
}

}

}
?>

但结果是:-

如果搜索“Sandeepan Nath”,它不会返回任何导师(而不仅仅是 Sandeepan 的行) 如果搜索“Sandeepan Class”,它将返回 Sandeepan 的行(而不是 Both coaches ) 如果搜索“Bob Class”,它会正确返回 Bob 的行 如果搜索“Bob Cratchit”,它不会返回任何导师(而不是仅返回

Please execute the following queries first to set up so that you can help me:-

CREATE TABLE IF NOT EXISTS `Tutor_Details` (
`id_tutor` int(10) NOT NULL auto_increment,
`firstname` varchar(100) NOT NULL default '',
`surname` varchar(155) NOT NULL default '',
PRIMARY KEY (`id_tutor`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=41 ;

INSERT INTO `Tutor_Details` (`id_tutor`,`firstname`, `surname`) VALUES
(1, 'Sandeepan', 'Nath'),
(2, 'Bob', 'Cratchit');   

CREATE TABLE IF NOT EXISTS `Classes` (
`id_class` int(10) unsigned NOT NULL auto_increment,
`id_tutor` int(10) unsigned NOT NULL default '0',
`class_name` varchar(255) default NULL,
PRIMARY KEY (`id_class`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=229 ;

INSERT INTO `Classes` (`id_class`,`class_name`, `id_tutor`) VALUES
(1, 'My Class', 1),
(2, 'Sandeepan Class', 2);

CREATE TABLE IF NOT EXISTS `Tags` (
`id_tag` int(10) unsigned NOT NULL auto_increment,
`tag` varchar(255) default NULL,
PRIMARY KEY (`id_tag`),
UNIQUE KEY `tag` (`tag`),
KEY `id_tag` (`id_tag`),
KEY `tag_2` (`tag`),
KEY `tag_3` (`tag`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=18 ;

INSERT INTO `Tags` (`id_tag`, `tag`) VALUES
(1, 'Bob'),
(6, 'Class'),
(2, 'Cratchit'),
(4, 'Nath'),
(3, 'Sandeepan'),
(5, 'My');

CREATE TABLE IF NOT EXISTS `Tutors_Tag_Relations` (
`id_tag` int(10) unsigned NOT NULL default '0',
`id_tutor` int(10) default NULL,
KEY `Tutors_Tag_Relations` (`id_tag`),
KEY `id_tutor` (`id_tutor`),
KEY `id_tag` (`id_tag`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `Tutors_Tag_Relations` (`id_tag`, `id_tutor`) VALUES
(3, 1),
(4, 1),
(1, 2),
(2, 2);

CREATE TABLE IF NOT EXISTS `Class_Tag_Relations` (
`id_tag` int(10) unsigned NOT NULL default '0',
`id_class` int(10) default NULL,
`id_tutor` int(10) NOT NULL,
KEY `Class_Tag_Relations` (`id_tag`),
KEY `id_class` (`id_class`),
KEY `id_tag` (`id_tag`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `Class_Tag_Relations` (`id_tag`, `id_class`, `id_tutor`) VALUES
(5, 1, 1),
(6, 1, 1),
(3, 2, 2),
(6, 2, 2);
  • In the present system data which I have given , tutor named "Sandeepan Nath" has has created class named "My Class" and tutor named "Bob Cratchit" has created class named "Sandeepan Class".

Requirement -

To execute a single query with limit on the results to show search results as per AND logic on the search keywords like this:-

  1. If "Sandeepan Class" is searched , Tutor Sandeepan Nath's record from Tutor Details table is returned(because "Sandeepan" is the firstname of Sandeepan Nath and Class is present in class name of Sandeepan's class)
  2. If "Class" is searched Both the tutors from the Tutor_details table are fetched because Class is present in the name of the class created by both the tutors.

Following is what I have so far achieved (PHP Mysql):-

<?php
$searchTerm1 = "Sandeepan";
$searchTerm2 = "Class";

mysql_select_db("test");


$sql = "SELECT td.*
FROM Tutor_Details AS td
LEFT JOIN Tutors_Tag_Relations AS ttagrels ON td.id_tutor = ttagrels.id_tutor
LEFT JOIN Classes AS wc ON td.id_tutor = wc.id_tutor
LEFT JOIN Class_Tag_Relations AS wtagrels ON td.id_tutor = wtagrels.id_tutor

LEFT JOIN Tags as t1 on ((t1.id_tag = ttagrels.id_tag) OR (t1.id_tag = wtagrels.id_tag))
LEFT JOIN Tags as t2 on ((t2.id_tag = ttagrels.id_tag) OR (t2.id_tag = wtagrels.id_tag))


where t1.tag LIKE '%".$searchTerm1."%'
AND t2.tag LIKE '%".$searchTerm2."%'

GROUP BY td.id_tutor
LIMIT 10
";

$result = mysql_query($sql);
echo $sql;
if($result)
{

while($rec = mysql_fetch_object($result)) $recs[] = $rec;
//$rec = mysql_fetch_object($result);
echo "<br><br>";

if(is_array($recs))
{
foreach($recs as $each)
{
print_r($each);
echo "<br>";
}

}

}
?>

But the results are :-

If "Sandeepan Nath" is searched, it does not return any tutor (instead of only Sandeepan's row)
If "Sandeepan Class" is searched, it returns Sandeepan's row (instead of Both tutors )
If "Bob Class" is searched, it correctly returns Bob's row
If "Bob Cratchit" is searched, it does not return any tutor (instead of only

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

晨敛清荷 2024-09-10 03:16:52

问题是您有 2 个搜索词,并且没有生成任何可以从同一个关系表中搜索两个标签的行(如果您查看查询结果而不将它们限制为 td,则很容易看出这一点, *)。如果您想在 SQL 中执行此操作,解决方案是生成用于每个导师/班级关系的标签的所有 2 个搜索词排列(同样,当您查看完整的查询结果时,该解释更有意义)。无论如何,这是我对修复 SQL 的方式的看法:

SELECT td.*
FROM Tutors_Tag_Relations AS ttagrels1 
JOIN Tutors_Tag_Relations AS ttagrels2 ON 
    ttagrels2.id_tutor = ttagrels1.id_tutor AND 
    ttagrels2.id_tag != ttagrels1.id_tag
JOIN Class_Tag_Relations AS wtagrels1 ON 
    wtagrels1.id_tutor = ttagrels1.id_tutor AND
    wtagrels1.id_tag != ttagrels1.id_tag AND
    wtagrels1.id_tag != ttagrels2.id_tag
JOIN Class_Tag_Relations AS wtagrels2 ON 
    wtagrels2.id_tutor = ttagrels1.id_tutor AND
    wtagrels2.id_tag != wtagrels1.id_tag AND
    wtagrels2.id_tag != ttagrels1.id_tag AND
    wtagrels2.id_tag != ttagrels2.id_tag
JOIN Tags as t1 ON
    t1.id_tag = ttagrels1.id_tag OR
    t1.id_tag = ttagrels2.id_tag OR
    t1.id_tag = wtagrels1.id_tag OR
    t1.id_tag = wtagrels2.id_tag
JOIN Tags as t2 ON
    t2.id_tag != t1.id_tag AND
    (t2.id_tag = ttagrels1.id_tag OR
    t2.id_tag = ttagrels2.id_tag OR
    t2.id_tag = wtagrels1.id_tag OR
    t2.id_tag = wtagrels2.id_tag)
LEFT JOIN Tutor_Details as td ON ttagrels1.id_tutor = td.id_tutor
LEFT JOIN Classes AS wc ON td.id_tutor = wc.id_tutor
WHERE 
    t1.tag LIKE '%Sandeepan%' AND
    t2.tag LIKE '%Nath%'
GROUP BY td.id_tutor

但这确实不是我会采取的方式。尝试通过连接进行这种搜索时,事情会变得非常非常繁重,如果添加更多搜索词,事情只会变得更糟。

缺少排列的说明:

这些表是通过删除 where 子句、group 子句、删除重复项并仅显示 td1 和 td2 列而生成的。

你的方式:

+--------+-----------+--------+-----------+
| id_tag | tag       | id_tag | tag       |
+--------+-----------+--------+-----------+
|      1 | Bob       |      3 | Sandeepan |
|      1 | Bob       |      6 | Class     |
|      2 | Cratchit  |      3 | Sandeepan |
|      2 | Cratchit  |      6 | Class     |
|      3 | Sandeepan |      1 | Bob       |
|      3 | Sandeepan |      2 | Cratchit  |
|      3 | Sandeepan |      5 | My        |
|      3 | Sandeepan |      6 | Class     |
|      4 | Nath      |      5 | My        |
|      4 | Nath      |      6 | Class     |
|      5 | My        |      3 | Sandeepan |
|      5 | My        |      4 | Nath      |
|      6 | Class     |      1 | Bob       |
|      6 | Class     |      2 | Cratchit  |
|      6 | Class     |      3 | Sandeepan |
|      6 | Class     |      4 | Nath      |
+--------+-----------+--------+-----------+

现在,如果我们看看这个,我们会发现 td1.id_tag 是从存在的班级或导师关系中生成的。 td2.id_Tag 也是根据现有的班级或导师关系生成的。但是,对于此结果的任何 1 行,td1.id_Tag 和 td2.id_tag 不能来自同一关系表。它们始终是“班级/导师”或“导师/班级”,从来没有一行用于“班级/班级”或“导师/导师”标签集(请记住,“班级关系”表中有一个 Sandeepan 标签)。这意味着您无法搜索“Sandeepan”、“Nash”或“Bob”、“Cratchit”,因为在这两种情况下,这些标签仅出现在一张表中。

我的方式:

+--------+-----------+--------+-----------+
| id_tag | tag       | id_tag | tag       |
+--------+-----------+--------+-----------+
|      1 | Bob       |      2 | Cratchit  |
|      1 | Bob       |      3 | Sandeepan |
|      1 | Bob       |      6 | Class     |
|      2 | Cratchit  |      1 | Bob       |
|      2 | Cratchit  |      3 | Sandeepan |
|      2 | Cratchit  |      6 | Class     |
|      3 | Sandeepan |      1 | Bob       |
|      3 | Sandeepan |      2 | Cratchit  |
|      3 | Sandeepan |      4 | Nath      |
|      3 | Sandeepan |      5 | My        |
|      3 | Sandeepan |      6 | Class     |
|      4 | Nath      |      3 | Sandeepan |
|      4 | Nath      |      5 | My        |
|      4 | Nath      |      6 | Class     |
|      5 | My        |      3 | Sandeepan |
|      5 | My        |      4 | Nath      |
|      5 | My        |      6 | Class     |
|      6 | Class     |      1 | Bob       |
|      6 | Class     |      2 | Cratchit  |
|      6 | Class     |      3 | Sandeepan |
|      6 | Class     |      4 | Nath      |
|      6 | Class     |      5 | My        |
+--------+-----------+--------+-----------+

我的 SQL 所做的就是生成丢失的班级/班级导师/导师行,这解决了问题。

Problem is that you have 2 search terms and you're not generating any rows in which you can search for two tags from the same relations table (this is easy to see if you look at the results from your query without restricting them to td,*). Solution, if you want to do it in SQL, is to generate all 2 search term permutations of the tags used for each tutor/class relation (again, that explanation makes a lot more sense when you look at the full query results). Anyhow, here's my take on fixing SQL the way you're doing it:

SELECT td.*
FROM Tutors_Tag_Relations AS ttagrels1 
JOIN Tutors_Tag_Relations AS ttagrels2 ON 
    ttagrels2.id_tutor = ttagrels1.id_tutor AND 
    ttagrels2.id_tag != ttagrels1.id_tag
JOIN Class_Tag_Relations AS wtagrels1 ON 
    wtagrels1.id_tutor = ttagrels1.id_tutor AND
    wtagrels1.id_tag != ttagrels1.id_tag AND
    wtagrels1.id_tag != ttagrels2.id_tag
JOIN Class_Tag_Relations AS wtagrels2 ON 
    wtagrels2.id_tutor = ttagrels1.id_tutor AND
    wtagrels2.id_tag != wtagrels1.id_tag AND
    wtagrels2.id_tag != ttagrels1.id_tag AND
    wtagrels2.id_tag != ttagrels2.id_tag
JOIN Tags as t1 ON
    t1.id_tag = ttagrels1.id_tag OR
    t1.id_tag = ttagrels2.id_tag OR
    t1.id_tag = wtagrels1.id_tag OR
    t1.id_tag = wtagrels2.id_tag
JOIN Tags as t2 ON
    t2.id_tag != t1.id_tag AND
    (t2.id_tag = ttagrels1.id_tag OR
    t2.id_tag = ttagrels2.id_tag OR
    t2.id_tag = wtagrels1.id_tag OR
    t2.id_tag = wtagrels2.id_tag)
LEFT JOIN Tutor_Details as td ON ttagrels1.id_tutor = td.id_tutor
LEFT JOIN Classes AS wc ON td.id_tutor = wc.id_tutor
WHERE 
    t1.tag LIKE '%Sandeepan%' AND
    t2.tag LIKE '%Nath%'
GROUP BY td.id_tutor

This really isn't how I'd go about it though. Things will get very, very heavy trying to do this kind of searching through joins and will only get worse if you add more search terms.

Explanation of missing permutation:

These tables are produced by removing the where clause, the group clause, removing duplicates and only showing the td1 and td2 columns.

Your way:

+--------+-----------+--------+-----------+
| id_tag | tag       | id_tag | tag       |
+--------+-----------+--------+-----------+
|      1 | Bob       |      3 | Sandeepan |
|      1 | Bob       |      6 | Class     |
|      2 | Cratchit  |      3 | Sandeepan |
|      2 | Cratchit  |      6 | Class     |
|      3 | Sandeepan |      1 | Bob       |
|      3 | Sandeepan |      2 | Cratchit  |
|      3 | Sandeepan |      5 | My        |
|      3 | Sandeepan |      6 | Class     |
|      4 | Nath      |      5 | My        |
|      4 | Nath      |      6 | Class     |
|      5 | My        |      3 | Sandeepan |
|      5 | My        |      4 | Nath      |
|      6 | Class     |      1 | Bob       |
|      6 | Class     |      2 | Cratchit  |
|      6 | Class     |      3 | Sandeepan |
|      6 | Class     |      4 | Nath      |
+--------+-----------+--------+-----------+

Now if we look at this we see that td1.id_tag is produced from either the class or tutors relations present. Also td2.id_Tag is produced from either the class or tutor relations present. However, for any 1 row of this result td1.id_Tag and td2.id_tag cannot be from the same relations table. They are always Class/Tutors or Tutors/Class there is never a row for a Class/Class or Tutors/Tutors set of tags (remember that there is a Sandeepan tag in the Class relations table). Which means there's no way for you to search "Sandeepan" "Nash" or "Bob" "Cratchit" because in both cases those tags are only present in one table.

My way:

+--------+-----------+--------+-----------+
| id_tag | tag       | id_tag | tag       |
+--------+-----------+--------+-----------+
|      1 | Bob       |      2 | Cratchit  |
|      1 | Bob       |      3 | Sandeepan |
|      1 | Bob       |      6 | Class     |
|      2 | Cratchit  |      1 | Bob       |
|      2 | Cratchit  |      3 | Sandeepan |
|      2 | Cratchit  |      6 | Class     |
|      3 | Sandeepan |      1 | Bob       |
|      3 | Sandeepan |      2 | Cratchit  |
|      3 | Sandeepan |      4 | Nath      |
|      3 | Sandeepan |      5 | My        |
|      3 | Sandeepan |      6 | Class     |
|      4 | Nath      |      3 | Sandeepan |
|      4 | Nath      |      5 | My        |
|      4 | Nath      |      6 | Class     |
|      5 | My        |      3 | Sandeepan |
|      5 | My        |      4 | Nath      |
|      5 | My        |      6 | Class     |
|      6 | Class     |      1 | Bob       |
|      6 | Class     |      2 | Cratchit  |
|      6 | Class     |      3 | Sandeepan |
|      6 | Class     |      4 | Nath      |
|      6 | Class     |      5 | My        |
+--------+-----------+--------+-----------+

All my SQL does is produce the missing Class/Class Tutors/Tutors rows ,which fixes the issue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文