我有一个新闻表如下
新闻:
| id | title | description
| 1 | Breaking news | bla bla bla
| 2 | Heavy snowfall in london | bla bla bla
一个Type表如下:
| id | type_name | type_code
| 1 | weather | 0567
| 2 | city | 0653
和一个NewsType表如下
|id | news_id | type_id | created_by |
| 1 | 2 | 1 | "John" |
| 2 | 2 | 2 | "Alex" |
从NewsType表中可以看出,单个新闻可以分为两种或更多类型。
我需要显示与类型相对应的新闻。用户可能会说给我关于城市和天气的所有新闻。要显示这个,我正在做类似的事情:
select distinct n.* , nt.created_at
from news n, newstype nt, type t where
n.id = nt.news_id and
t.id = nt.type_id
order by nt.created_at
limit 25
问题是这个查询两次返回相同的消息(我认为这是因为我正在做的内连接)。我应该在查询中更改什么,以便如果新闻被分类为两种类型,并且用户请求查看相同的两种类型的新闻,我只获得单个新闻项?而不是两个!
答案 0 :(得分:5)
简单的解决方案:
select * from news where news_id in (
select news_id
from NewsType
where type_id in (the types you want)
)
大多数人会说你应该在内部查询的news_id上添加一个DISTINCT。你可以试试,但我很确定它会降低性能。
总而言之,如果您认为此解决方案效果不佳,您可以将内部查询设置为CTE,这通常表现得更好:
with my_CTE as(
select news_id
from NewsType
where type_id in (the types you want)
)
select *
from news
where news_id in (select news_id from my_CTE)
答案 1 :(得分:2)
group by
是另一种方法:
select n.id, n.title, n.description, max(nt.created_at)
from news n, newstype nt, type t where
n.id = nt.news_id and
t.id = nt.type_id
group by n.id, n.title, n.description
order by nt.created_at
limit 25
答案 2 :(得分:0)
您想要选择具有针对特定类型的NewsType表中的条目的所有故事。因此,您希望选择与该类型存在关系的新闻项目:
SELECT
News.ID,
News.Title,
News.Description
FROM
News
WHERE
EXISTS
(SELECT
NULL
FROM
NewsType
INNER JOIN Type ON NewsType.Type_ID = Type.ID
WHERE
News.ID = NewsType.News_ID
AND Type.Type_Code = @typeCode)
如果使用类型名称作为参数,则可能需要将where子句的最后一行更改为Type.Type_Name = @typeName
答案 3 :(得分:0)
尝试
select distinct n.id, n.title, n.description
但是,正如@Jan Dvorak所说,
select distinct n.*
不应该选择相同的新闻两次
答案 4 :(得分:0)
您需要决定如何处理“重复”类型:您是否只想为与多种类型相关联的新闻项目显示一种类型,或者您是否要将它们全部列出?
如果是后者,您可以使用string_agg函数进行调查,请参阅http://www.postgresql.org/docs/9.2/static/functions-aggregate.html
select distinct n.id, n.title, n.description, string_agg(t.type_name, ',')
from news n, newstype nt, type t where
n.id = nt.news_id and
t.id = nt.type_id
group by n.id, n.title, n.description
limit 25