7

我有一个新闻表如下

消息:

| id  | title                       | description
| 1   | Breaking news               | bla bla bla
| 2   | Heavy snowfall in london    | bla bla bla

a 类型表如下:

| 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

问题是这个查询两次返回相同的消息(我认为这是因为我正在做的内部连接)。我应该在查询中进行什么更改,以便如果新闻被分类为两种类型,并且用户请求查看相同的两种类型的新闻,我只能得到单个新闻项?而不是两个!

4

5 回答 5

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)
于 2012-10-23T11:12:18.030 回答
2

Agroup 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
于 2012-10-23T11:39:58.977 回答
1

尝试

select distinct n.id, n.title, n.description

但是,正如@Jan Dvorak 所说,

select distinct n.*

不应该两次选择相同的新闻

于 2012-10-23T11:04:56.220 回答
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

于 2012-10-23T11:04:24.117 回答
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
于 2012-10-23T11:08:05.143 回答