2015-11-23 129 views
1

我试图使SELECT查询基于另外两个表数据。 _sites_数组有5个对象,_cats_数组现在有12个对象。因此,为了基于这些对象获得news,我必须重复执行12 * 5 sql查询。 (对于每个类别&站点)MySQL根据两个表选择行

如何减少查询次数?

getSites(function (_sites_) { 
    getCategories(function (_cats_) { 

     var array = [] 

     async.each(_sites_, function (site, next) { 
      async.each(_cats_, function (cat, next2) { 

       var sql = "SELECT * "+ 
          "FROM news "+ 
          "WHERE category = ? AND site = ? "+ 
          "ORDER BY id DESC LIMIT 30" 

       db.query(sql, [cat.data, site.data], function (result) { 
        array = array.concat(temp) 
        next2() 
       }) 

      }, function() { 
       next() 
      }) 

     }, function() { 
      // finished 
      console.log(array) 
     }) 

    }) 
}) 


function getCats (pass) { //get used categories 
    db.query("SELECT * FROM cat WHERE cat_name in (SELECT news_url.rss_cat FROM news_url)"+ 
      "ORDER by cat_pos ASC", [], function (result) { 
       var array = [] 

       if(result) { 
        for (var j = 0; j < result.length; j++) { 
         array.push({type: 1, data:result[j].cat_name}) 
        }; 
       } 

       pass(array) 
    }) 
} 


function getSites (pass) { 
    db.query("SELECT * FROM news_url", [], function (result) { 

     var array = [] 

     if(result) { 
      for (var j = 0; j < result.length; j++) { 
       array.push({type: 0, data:result[j].rss_site}) 
      }; 
     } 

     pass(array) 
    }) 
} 

表:(类别)

|id|cat_name|cat_pos| 
|1 |Fun  | 1  | 
|1 |Bomm | 2  | 

news_url表:(RSS网站名称和URL)

|id|rss_site|rss_url |rss_cat 
|1 |Cnn  |http://...|Fun 
|2 |Fox  |http://...|Bomm 
|3 |Cnn  |http://...|Bomm 
|4 |Routers |http://...|Fun 

新闻表:

|id|news_site | news_cat | news_content 
|1 | Cnn  | Bomm  | Some random news content from Cnn 
|2 | Cnn  | Fun  | Some random news content from Cnn 
|3 | Fox  | Fun  | Some random news content from Fox 

预期结果是每个类别和网站组合的单独N行限制。如果可以使用一些查询。

+1

有没有一种方法可以在一个查询中加入表格?这听起来可能,但没有看到一些示例数据和预期结果(或至少你的表结构),我不知道。 – AdamMc331

+0

我根据您的建议更新了我的问题,谢谢。 – Lazy

+0

那么,你的意思是每个类别和网站的组合?只是列表中的(cnn,fun),(cnn,bomm),(狐狸,趣味),(狐狸,波恩) – AdamMc331

回答

1

如果您不想为每个网站的每个类别单独查询,那么为什么要这样做?如果您只是忽略您现在使用的查询中的WHERE条款,那么一次性将会为您提供所有类别和网站的所有新闻,但要根据您放置的30行LIMIT进行。

如果您想针对类别和网站的每个组合分别显示30行限制,这是比较棘手的,因为您目前的方法提供了此功能,但我倾向于怀疑LIMIT未达到您想要的水平现在要做,或者至少如果你有更多的数据它不会这样做。

编辑补充:

如果,你在评论表明,你真的想为类别和网站的每个组合的30行的限制的话,MySQL的,我看到的只有两种选择:

  • 通过连接现在通过UNION ALL运算符执行的所有单个查询,形成一个巨大查询。仅提交该查询。这可能是你最好的选择,但是你也可以使用子句的简单查询,如我第一次建议的那样,并且在node.js端应用行限制。这种方法可以通过网站和类别额外订购来促进。虽然这会导致更简单的查询,但可能涉及许多行正在传输然后被丢弃。
+0

正如您所说,我想为每个类别和网站的组合分别限制30行。这是我想要达到的。所以LIMIT很重要。 – Lazy

+0

谢谢你的建议。我会和第二个一起去。 – Lazy

0

你的SQL也许应该是这样的:

var sql = "SELECT * "+ "FROM news "+ "WHERE category in (?) AND site in (?) "+ "ORDER BY id DESC LIMIT 30"

因为你有两个数组,而不仅仅是两个值。

1

这听起来像你正在寻找一个笛卡尔积。当你从两个不同的表中选择而不定义它们之间的关系时,你会得到这个结果。因此,举个简单的例子:

SELECT rss_site, cat_name 
FROM categories, news_url; 

会返回每一个可能的(rss_site,cat_name)组合。我会注意,但是,既然你(在样本数据CNN)有一些重复rss_site值,您可能想在您的SELECT子句添加DISTINCT只得到不同对:

SELECT DISTINCT rss_site, cat_name 
FROM categories, news_url; 

下面是一个SQL Fiddle例子。

+0

谢谢。但是,如何使用此笛卡尔每个组合的N行限制从新闻表中获取新闻?我最大的问题是这个。但是你的帮助绝对有帮助。 – Lazy

+0

@Lazy这里有几个问题标记为[tag:most-n-per-group]是你在找什么?我会尝试相应地编辑我的答案。 – AdamMc331

+0

其实我只是粗暴地诚实,我可能无法立即编辑,但我会尝试稍后再回来一个示例查询,当我可以。如果你最终解决它,让我知道! – AdamMc331