- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用手动分配的类别来分析推文。一切都存储在 MySQL 数据库中。我可以毫无问题地添加和删除推文、类别以及它们之间的关系。
使用 OR 逻辑包括类别按预期工作。如果我想找到分类为“Venezuela”或“Maduro”的推文,我将这两个术语发送到名为 $include
的数组中,并将 $include_logic
设置为 “或”
。返回分类在任一类别下的推文。太棒了!
当我尝试使用 AND 逻辑(即分类为 所有 的推文包含术语,例如委内瑞拉 和 Maduro)或当我尝试排除时,问题就开始了类别。
代码如下:
function filter_tweets($db, $user_id, $from_utc, $to_utc, $include = null, $include_logic = null, $exclude = null) {
$include_sql = '';
if (isset($include)) {
$include_sql = 'AND (';
$logic_op = '';
foreach ($include as $cat) {
$include_sql .= "{$logic_op}cats.name = '$cat' ";
$logic_op = ($include_logic != 'and') ? 'OR ' : 'AND '; # AND doesn't work here
}
$include_sql .= ')';
}
$exclude_sql = ''; # Nothing I've tried with this works.
$sql = "
SELECT DISTINCT tweets.id FROM tweets
LEFT OUTER JOIN tweets_cats ON tweets.id = tweets_cats.tweet_id
LEFT OUTER JOIN cats ON tweets_cats.cat_id = cats.id
WHERE tweets.user_id = $user_id
AND created_at
BETWEEN '{$from_utc->format('Y-m-d H:i:s')}'
AND '{$to_utc->format('Y-m-d H:i:s')}'
$include_sql
$exclude_sql
ORDER BY tweets.created_at ASC;";
return db_fetch_all($db, $sql);
}
db_fetch_all()
在哪里
function db_fetch_all($con, $sql) {
if ($result = mysqli_query($con, $sql)) {
$rows = mysqli_fetch_all($result);
mysqli_free_result($result);
return $rows;
}
die("Failed: " . mysqli_error($con));
}
and tweets_cats
是 tweets
和 cats
表之间的连接表。
在阅读了联接和联结表之后,我明白了为什么我的代码在上述两种情况下不起作用。它一次只能查看一条推文和相应的类别。因此,要求它忽略归类为“X”的推文是没有实际意义的,因为当遇到相同的推文并归类为“Y”时它不会忽略它。
我不明白的是如何修改代码以使其正常工作。我还没有找到任何人试图做类似事情的例子。也许我没有在寻找合适的术语。如果有人能给我指出一个很好的资源,让我在 MySQL 中使用与我使用它们的方式类似的联结表,我将不胜感激。
SELECT DISTINCT tweets.id FROM tweets
LEFT OUTER JOIN tweets_cats ON tweets.id = tweets_cats.tweet_id
LEFT OUTER JOIN cats ON tweets_cats.cat_id = cats.id
WHERE tweets.user_id = 818910970567344128
AND created_at BETWEEN '2019-02-01 05:00:00' AND '2019-03-01 05:00:00'
AND (cats.name = 'Venezuela' OR cats.name = 'Maduro' )
ORDER BY tweets.created_at ASC;
SELECT tweets.id FROM tweets
LEFT OUTER JOIN tweets_cats ON tweets.id = tweets_cats.tweet_id
LEFT OUTER JOIN cats ON tweets_cats.cat_id = cats.id
WHERE tweets.user_id = 818910970567344128
AND created_at BETWEEN '2019-02-01 05:00:00' AND '2019-03-01 05:00:00'
AND cats.name IN ('Venezuela', 'Maduro')
GROUP BY tweets.id
HAVING COUNT(*) = 2
ORDER BY tweets.created_at ASC;
不过,这有点超出我对 SQL 的理解。我很高兴它有效。我只是希望我了解如何做。
SELECT id FROM tweets
WHERE user_id = 818910970567344128
AND created_at BETWEEN '2019-02-01 05:00:00' AND '2019-03-01 05:00:00'
AND id NOT IN (
SELECT tweets.id FROM tweets
LEFT OUTER JOIN tweets_cats ON tweets.id = tweets_cats.tweet_id
LEFT OUTER JOIN cats ON tweets_cats.cat_id = cats.id
WHERE tweets.user_id = 818910970567344128
AND created_at BETWEEN '2019-02-01 05:00:00' AND '2019-03-01 05:00:00'
AND cats.name IN ('Venezuela','Maduro')
)
ORDER BY created_at ASC;
function filter_tweets($db, $user_id, $from_utc, $to_utc,
$include = null, $include_logic = null,
$exclude = null, $exclude_logic = null) {
if (isset($exclude)) {
$exclude_sql = "
AND tweets.id NOT IN (\n"
. include_tweets($user_id, $from_utc, $to_utc, $exclude, $exclude_logic)
. "\n)";
} else {
$exclude_sql = '';
}
if (isset($include)) {
$sql = include_tweets($user_id, $from_utc, $to_utc, $include, $include_logic, $exclude_sql);
} else {
$sql = "
SELECT id FROM tweets
WHERE user_id = $user_id
AND created_at
BETWEEN '{$from_utc->format('Y-m-d H:i:s')}'
AND '{$to_utc ->format('Y-m-d H:i:s')}'
$exclude_sql";
}
$sql .= "\nORDER BY tweets.created_at ASC;";
return db_fetch_all($db, $sql);
}
它依赖于这个额外的函数来生成 SQL:
function include_tweets($user_id, $from_utc, $to_utc, $include, $logic, $exclude_sql = '') {
$group_sql = '';
$include_sql = 'AND cats.name IN (';
$comma = '';
foreach ($include as $cat) {
$include_sql .= "$comma'$cat'";
$comma = ',';
}
$include_sql .= ')';
if ($logic == 'and')
$group_sql = 'GROUP BY tweets.id HAVING COUNT(*) = ' . count($include);
return "
SELECT tweets.id FROM tweets
LEFT OUTER JOIN tweets_cats ON tweets.id = tweets_cats.tweet_id
LEFT OUTER JOIN cats ON tweets_cats.cat_id = cats.id
WHERE tweets.user_id = $user_id
AND created_at
BETWEEN '{$from_utc->format('Y-m-d H:i:s')}'
AND '{$to_utc ->format('Y-m-d H:i:s')}'
$include_sql
$group_sql
$exclude_sql";
}
最佳答案
执行此操作的一种方法是多次将您的 tweets
表与联结表连接起来,例如像这样:
SELECT tweets.*
FROM tweets
JOIN tweet_cats AS tweet_cats_foo
ON tweet_cats_foo.tweet_id = tweets.id
JOIN tweet_cats AS tweet_cats_bar
ON tweet_cats_bar.tweet_id = tweets.id
WHERE
tweet_cats_foo.name = 'foo' AND tweet_cats_bar.name = 'bar'
或者,等价地,像这样:
SELECT tweets.*
FROM tweets
JOIN tweet_cats AS tweet_cats_foo
ON tweet_cats_foo.tweet_id = tweets.id
AND tweet_cats_foo.name = 'foo'
JOIN tweet_cats AS tweet_cats_bar
ON tweet_cats_bar.tweet_id = tweets.id
AND tweet_cats_bar.name = 'bar'
请注意,为简单起见,我在上面假设您的联结表直接包含类别名称。如果您坚持使用数字类别 ID 但按名称搜索类别,我建议创建一个 View ,使用数字类别 ID 将类别和联结表连接在一起,并在查询中使用该 View 而不是实际的联结表。这使您不必为了查找数字类别 ID 而在查询中包含一大堆不必要的样板代码。
对于排除查询,您可以使用 LEFT JOIN
并检查联结表中是否不存在匹配记录(在这种情况下,该表中的所有列都将为 NULL
),像这样:
SELECT tweets.*
FROM tweets
LEFT JOIN tweet_cats AS tweet_cats_foo
ON tweet_cats_foo.tweet_id = tweets.id
AND tweet_cats_foo.name = 'foo'
WHERE
tweet_cats_foo.tweet_id IS NULL -- could use any non-null column here
(使用此方法,您确实需要在 LEFT JOIN
子句中包含 tweet_cats_foo.name = 'foo'
条件,而不是 WHERE
子句。)
当然,你也可以把这些结合起来。例如,要查找类别 foo
但不在 bar
中的推文,您可以这样做:
SELECT tweets.*
FROM tweets
JOIN tweet_cats AS tweet_cats_foo
ON tweet_cats_foo.tweet_id = tweets.id
AND tweet_cats_foo.name = 'foo'
LEFT JOIN tweet_cats AS tweet_cats_bar
ON tweet_cats_bar.tweet_id = tweets.id
AND tweet_cats_bar.name = 'bar'
WHERE
tweet_cats_bar.tweet_id IS NULL
或者,同样等价地:
SELECT tweets.*
FROM tweets
LEFT JOIN tweet_cats AS tweet_cats_foo
ON tweet_cats_foo.tweet_id = tweets.id
AND tweet_cats_foo.name = 'foo'
LEFT JOIN tweet_cats AS tweet_cats_bar
ON tweet_cats_bar.tweet_id = tweets.id
AND tweet_cats_bar.name = 'bar'
WHERE
tweet_cats_foo.tweet_id IS NOT NULL
AND tweet_cats_bar.tweet_id IS NULL
附言。另一种查找类别交叉点的方法,as suggested by Strawberry in the comments above ,是针对联结表执行单个连接,按推文 ID 对结果进行分组,并使用 HAVING
子句来计算为每条推文找到了多少个匹配类别:
SELECT tweets.*
FROM tweets
JOIN tweet_cats ON tweet_cats.tweet_id = tweets.id
WHERE
tweet_cats.name IN ('foo', 'bar')
GROUP BY tweets.id
HAVING COUNT(DISTINCT tweet_cats.name) = 2
此方法也可以通过使用第二个(左)连接来推广以处理排除,例如像这样:
SELECT tweets.*
FROM tweets
JOIN tweet_cats AS tweet_cats_wanted
ON tweet_cats_wanted.tweet_id = tweets.id
AND tweet_cats_wanted.name IN ('foo', 'bar')
LEFT JOIN tweet_cats AS tweet_cats_unwanted
ON tweet_cats_unwanted.tweet_id = tweets.id
AND tweet_cats_unwanted.name IN ('baz', 'blorgh', 'xyzzy')
WHERE
tweet_cats_unwanted.tweet_id IS NULL
GROUP BY tweets.id
HAVING COUNT(DISTINCT tweet_cats_wanted.name) = 2
我没有对这两种方法进行基准测试以确定哪一种更有效,我强烈建议您在决定使用哪一种之前先这样做。原则上,我希望数据库引擎更容易优化多重连接方法,因为它清楚地映射到连接的交集,而对于 GROUP BY
... HAVING
方法一个天真的数据库可能最终会浪费大量的精力首先找到匹配任何类别的所有推文,然后才将 HAVING
子句应用于过滤掉所有匹配所有类别的内容。一个简单的测试用例可以是几个非常大的类别与一个非常小的类别的交集,我期望使用多重连接方法会更有效。但当然,人们应该经常测试这些东西,而不是仅仅依靠直觉。
关于php - 在 PHP 和 MySQL 中使用联结表来分类和包含和排除类别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54612224/
关闭。这个问题是opinion-based .它目前不接受答案。 想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题. 9 个月前关闭。 Improve
我使用 partykit打包并遇到以下错误消息: Error in matrix(0, nrow = mi, ncol = nl) : invalid 'nrow' value (too large
我一直在尝试寻找一个量表或分类指标,为 VADER 情绪分析分配一些情感程度,而不仅仅是积极、消极或中性。如果有人可以分享他们的观点或资源来帮助按以下方式对 VADER 复合分数进行分类,我将非常感激
伙计们,我想自动循环..但我不知道是我放错了 while 还是循环错了? 我的数据库 标签:kt_barang kd_kategori | nama_kategori 1
我正在创建一个列出本地企业并按类别、子类别和关键字对它们进行分组的应用程序。以下是企业排序规则: 一个企业可以属于多个类别和子类别 一个企业可以有多个关键字 并非每个类别都有子类别,但有子类别的只有两
我有一系列单词 - 我的刺激 - 它们显示在屏幕上。然而,每个词都有另一个“条件”,即它们是类别 A、类别 B 或类别 C。这可能很简单,但我找不到答案并坚持下去。我的最终目标是在每次运行脚本时将类别
我正在使用 Laravel 5.5 和 MySql。如果不向 Services 表中添加 subCategoryID 列,我无法弄清楚如何将类别和子类别与服务相关联。 目前这是我的表结构 服务类别 i
我有两个部分/类别结构的链接表。 the section table structure id sec_title 1 section 1 2 section 2 the category str
我有一个类层次结构如下 @interface PTLDatasource : NSObject ... @interface PTLFetchedDatasource : PTLDatasource
我有一个 DataFrame df 一列,category 使用以下代码创建: import pandas as pd import random as rand from string import
我经常在多个类中设置获取请求以从核心数据(加上一些其他结果)中检索“allRecipes”或“lastModifiedDate”。 为此使用专门的类别 NSManagedObjectContext+R
可以在 Objective C 中创建类别之间的依赖关系吗?也在类别和它们的基类之间? 我知道在运行时应该没有区别,它们可能只是在编译时合并在一起。例如,假设我将 B 类分解为: B(base cla
这个问题在这里已经有了答案: 关闭 10 年前。
example img of a category selection by user 嘿,我正在尝试设置一个选择,用户必须选择一个类别和第二个类别,但我不知道如何获取他单击的信息。用户单击类别后,它
尝试将投资组合库添加到我正在制作的自定义 wp 主题中。我已经筋疲力尽地试图寻找甚至可以修改一些的解决方案和插件。我认为我在寻找解决方案时遇到的一个问题是我不完全确定哪些搜索词可以帮助我找到与我想要实
当我查看 Cocoa Touch API 时,我可以在同一个头文件中找到一些与类别一起声明的类,例如 @interface NSArray : NSObject @property (readonl
我的 log4j.properties 中有以下内容 log4j.rootLogger = debug, stdout, fileLog log4j.appender.stdout = org.apa
如果我在类中添加类别方法,比如NSXMLNode: @interface NSXMLNode (mycat) - (void)myFunc; @end NSXMLNode 的子类,例如 NSXMLEl
先说场景,wordpress的分类结构是这样的 Level 1: Top Level 2: -Nextme_1 Level 3: --Nextme_2 --Nextme_3 Leve
我有一个解析网络,现在我想浏览标签,或显示图表。我怎样才能得到图表?或者在树中导航。显示第一步然后其他等。并了解这棵树是如何 build 的。 import urllib from lxml impo
我是一名优秀的程序员,十分优秀!