0

我希望我能把我的问题说清楚。

我有一个名为的表tweets,我想从中提取daterange表中每个数据的信息。该表包含 142 个日期,其中 102 个日期的属性trading(开市日)设置为 1 ( trading=1)。

下面的查询从tweets表中提取 20 家公司(用 标识sp100_id)的信息。因此,预期的结果集包含 20 x 102 = 2,040 行。但是,我只返回了 1,987 行,因为对于某些日期公司组合,该tweets表不包含任何数据。但是,我需要将这些“空天”包含在结果集中。我想我可以通过使用COALESCE(X, 0),0如果没有数据就返回,但结果是一样的:1,987 行。

根据这些信息和下面的查询,有人知道我如何让它为表中的每个返回 102 行(每个daterange._date带有1 行trading=1)吗?sp100_idtweets

SELECT
  sp100.sp100_id,
  daterange._date,
  COALESCE(SUM(IF(tweets.classify1=2, tweets.`retweet_count`, 0)),0) AS `pos-retweet`,
  COALESCE(SUM(IF(tweets.classify1=2, tweets.`user-quality`,  0)),0) AS `pos-quality`,
  COALESCE(SUM(IF(tweets.classify1=2, tweets.`follow`,        0)),0) AS `pos-follow`,
  COALESCE(SUM(IF(tweets.classify1=3, tweets.`retweet_count`, 0)),0) AS `neg-retweet`,
  COALESCE(SUM(IF(tweets.classify1=3, tweets.`user-quality`,  0)),0) AS `neg-quality`,
  COALESCE(SUM(IF(tweets.classify1=3, tweets.`follow`,        0)),0) AS `neg-follow`
FROM
  sp100
CROSS JOIN
  daterange
LEFT JOIN
  tweets
  ON tweets.nyse_date = daterange._date
  AND tweets.sp100_id  = sp100.sp100_id
WHERE sp100.sp100_id BETWEEN 1 AND 20 AND tweets.type != 1 AND daterange.trading = 1
GROUP BY
  sp100.sp100_id, daterange._date

在任何其他情况下,我都会为您提供一个 SQLFiddle,但是要导出用于 SQLFiddle 的表的适当部分将是很多工作,而解决方案可能对一些真正的 SQL 大师来说是清楚的 :-)

4

2 回答 2

2

问题来自tweets.type != 1在您的WHERE条款中要求。

对于没有关联推文的日期,外部连接将导致所有tweets列,包括tweets.typeNULL。如使用NULL下所述:

因为任何算术比较的结果NULL也是NULL,所以您无法从此类比较中获得任何有意义的结果。

在 MySQL 中,0orNULL表示 false,其他任何表示 true。布尔运算的默认真值是1.

因此,此类记录由您的WHERE子句过滤。

正如@Martin Smith 评论的那样,您可以将此过滤条件移动到ON外部联接的子句中(以便仅针对实际tweets记录而不是模拟记录执行测试NULL)。

或者,您可以重写过滤器以处理NULL. 例如,使用NULL-safe 相等运算符

NOT tweets.type <=> 1

顺便说一句,我通常不关心daterange表格,而是省略结果集中没有数据的日期:相反,我在我的应用程序代码中处理丢失的日期。

于 2012-09-03T00:01:15.283 回答
0

您需要一个充满每一天的日历表。我知道这听起来可能很傻,但是这个解决方案可以解决很多问题。整数也可以使用相同的解决方案(整数表)

于 2012-09-02T20:52:02.997 回答