2012-04-19 151 views
3

我正在使用以下查询来搜索标题中包含术语的产品。查询返回所需的结果(通常结果太多)。每组选择前x条记录

现在我只希望它能够为每家公司选择最多3个(随机)产品。有些公司返回多条记录/产品,但我只需要承担3并移动到下一个公司

SELECT p.title As entryname, cname 
FROM company c, product p 
WHERE p.title LIKE '%steel%' AND p.cid = c.cid 
GROUP By cname, ca.title 

我试图理解由分区排名的事情,但我没有得到太远。我使用的MS SQL

+2

你真的是指随机而非随意吗?你的目标是什么数据库。这个问题的解决方案或DB特定的 – 2012-04-19 21:38:09

+0

Conrad,Am使用MS SQL web版。通过随机,我的意思是前3个选定的产品不必是相同的所有...如果是100个产品的公司x,100中的任何3个可以做 – 2012-04-19 21:44:30

+0

好吧,因为WEB版本直到2008年才开始尽我所知,我已将标签添加到您的问题 – 2012-04-19 21:48:26

回答

7

您可以使用ROW_NUMBER()来做到这一点

with cte as (
SELECT 
    p.title as entryname, cname, 
    ROW_NUMBER() OVER (PARTITION BY c.id ORDER BY p.id) rn 
FROM company c 
    INNER JOIN product p 
    ON p.cid = c.cid 
WHERE p.title LIKE '%steel%' 
GROUP By cname, ca.title  
) 
SELECT 
    p.title as entryname, cname, 
FROM CTE where rn <= 3 

如果你真的想随机的(而不是3具有最低ID),您可以将ROW_NUMBER行更改为

ROW_NUMBER() OVER (PARTITION BY c.id order by newid()) rn

0

如果你的数据库是SQL服务器(在您的文章的末尾都会响起MS SQL的),查找TOP on MSDN

SELECT TOP(3) p.title As entryname, cname 
FROM company c, product p 
WHERE p.title LIKE '%steel%' AND p.cid = c.cid 
GROUP By cname, ca.title 

对于Oracle,你会在哪里使用rownum条款:

SELECT p.title As entryname, cname 
FROM company c, product p 
WHERE p.title LIKE '%steel%' AND p.cid = c.cid AND rownum < 4 
GROUP By cname, ca.title 
+0

OP要求每个公司的TOP 3产品。 – 2012-04-19 21:42:05

+0

DuraCell,这只返回整个集合的TOP3。它应该为每个公司返回1 2或最多3个产品 – 2012-04-19 21:52:07

0

你可以简单地追加

limit 3,5 

到您的查询的末尾。作为一个例子,这会给你有序排列从第3行开始的5行。

现在选择这5行randonly是模式复杂的东西,我猜。

+0

这是MySQL语法,事实证明是SQL Server。另外它的错误,运营商希望每个公司3个产品,而不是所有公司的3个,因此,添加限制3.5不会这样做 – 2012-04-19 22:01:41

+0

@ConradFrix。是的,你是对的,这是错的。下次我会两次读这个问题。谢谢! – 2012-04-19 22:08:59