2012-03-26 65 views
-2

我有一个表“文章”,有一列“公司”,其中有公司名单或文章类型 - 蹩脚我知道,但它不是我的数据库。 :)假设有 n每种类型的文章。我需要选择属于该类型的第一篇文章(基于年份或任何其他标准)。就像这样:通过字符串和限制MySQL查询

select * from details where (company = 'aaa' or company = 'bbb' or ...) 

我知道类型是什么,所以他们可以硬编码。我只需要限制每种类型的第一篇文章。谢谢!

EDIT

给定的采样数据

 
id company copy issue 
------------------------ 
1 apple 'abc' NULL 
2 bmw  'abc' NULL 
3 ibm  'abc' NULL 
4 news  'abc' 2 
5 news  'abc' 3 
6 seagate 'abc' NULL 
7 events 'abc' 1 
8 features 'abc' 5 
9 samsung 'abc' NULL 

我需要的行4,7,8。

EDIT2

对不起,如果我不清楚。本质上,表格包含两种不同类型的数据。一个是公司信息,一个是文章信息。基本上我需要这样做:

select * from articles where company = "news" order by issue limit 1; 
select * from articles where company = "events" order by issue limit 1; 
select * from articles where company = "features" order by issue limit 1; 

但只有一个查询。

+0

这确实取决于标准。 MySQL很难在单个查询中仅选择组中第一个匹配行的字段。 – gahooa 2012-03-26 03:29:25

+0

您的可排序数据在哪里? #5之前排第4排的是什么?另外,我看不出#7和#8有什么区别。为什么不#1,#2,#3等? – Phil 2012-03-26 03:32:01

+0

这就是数据输入的方式,id是一个自动增量。这比这更复杂一点,但为了方便起见,让我们假设它只是id不同。 – Alex 2012-03-26 03:35:21

回答

3

像这样的事情也许

select * from details d 
where company in ('news', 'events', 'features') 
and not exists (
    select 1 from details d_ 
    where d_.company = d.company 
    and d_.id < d.id -- provide your sortable criteria here 
) 

例在这里 - http://sqlfiddle.com/#!2/bb8f2/6

+0

这将工作,但公司是混合类型col:它可以表示公司或文章类型。 – Alex 2012-03-26 03:31:47

+0

@Alex我已将Mosty的答案添加到SQLFiddle中,以便您可以比较两者。 – Phil 2012-03-26 03:53:16

+0

随着一些玩耍,这似乎是伎俩。谢谢! – Alex 2012-03-26 04:07:49

0

假设 “公司” 和 “publication_date” 在表中 “详细信息” 栏,然后是这样的:

select * 
from details 
where company in ('aaa', 'bbb', ...) 
and publication_date between '2012-02-01' and '2012-03-01' 
order by publication_date desc 
limit 1 
+0

IN子句正是我所需要的,但我也需要将每种类型限制为仅第一种。所以如果查询返回4'aaa'和7'bbb'我只需要每个的第一个。 – Alex 2012-03-26 03:33:43

3

此查询:

select t1.* from t t1 
left join t t2 
on t1.company = t2.company and t1.id > t2.id 
where t2.id is null and t1.company in ('news', 'events', 'features') 

将返回:

 
+----+----------+------+ 
| ID | COMPANY | COPY | 
+----+----------+------+ 
| 4 | news  | abc | 
| 7 | events | abc | 
| 8 | features | abc | 
+----+----------+------+ 

这就是你想要的?

注意:当你说the first article我假设的顺序由ID领域提供

你可以用它玩here

编辑:

您的编辑后,查询几乎是同样,只是将订购字段更改为issue而不是id

select t1.* from t t1 
left join t t2 
on t1.company = t2.company and t1.issue > t2.issue 
where t2.id is null and t1.company in ('news', 'events', 'features') 
+0

对不起,使事情变得复杂:它可能是id,也可能是日期,或杂志问题还没有得到方向......什么是你的查询中的“t”,“t1”,“t2”? – Alex 2012-03-26 03:40:58

+0

't'是表名。 't1'和't2'是表别名。我不明白你对不同顺序的看法。我提供的解决方案会导致您的预期结果。你能否更新你的示例数据来显示你的实际数据,看看为什么这不起作用?谢谢 – 2012-03-26 03:43:46

0

您正在尝试执行group by
接下来要order by问题列。
然后你只需要第一行。

我用组连接创建一个列表,
然后提取有序列表group_concat(copy order by copy)中的第一个字符串。

select 
    id, 
    company, 
    substring(
    group_concat(copy order by copy), 
    1, 
    case when substring_index(group_concat(copy order by copy),',',1) > 1 
      then substring_index(group_concat(copy order by copy),',',1)-1 
     else 1 end 
    ) as copy 
from details d 
where company in ('news', 'events', 'features') 
group by company 

*名单group_concat(copy order by copy)不能太长,虽然,这取决于你的数据。