【问题标题】:Restricting the records returned to unique with SQL query使用 SQL 查询将返回的记录限制为唯一
【发布时间】:2017-07-02 19:27:39
【问题描述】:

我正在使用 Microsoft Access 来设计一个查询(我最终将在我的 MFC 应用程序中提取并使用它。到目前为止,我有这个:

SQL 视图是:

SELECT [Congregation Speaker Talks].talkno, [Congregation Speaker Talks].congregation
FROM [Congregation Speaker Talks]
WHERE ((([Congregation Speaker Talks].congregation)<>'Keynsham'))
ORDER BY [Congregation Speaker Talks].talkno;

目前的结果是:

所以它正在工作,因为没有列出值为 Keynsham 的记录。但正如你所看到的,有来自不同会众的多位演讲者进行了第 1 次演讲。我只希望这个数字出现一次。我尝试使用DISTINCT,但它不起作用。

更新

这有点帮助:

SQL "select where not in subquery" returns no results

我向您展示了我所做的,但我想避免将查询实际添加到表中。

第 1 步 我创建了一个查询并将其保存为KeynshamTalks

SELECT [Public Talk Titles].[Talk Number]
FROM [Public Talk Titles] INNER JOIN [Congregation Speaker Talks] ON [Public Talk Titles].[Talk Number] = [Congregation Speaker Talks].talkno
WHERE ((([Congregation Speaker Talks].congregation)="Keynsham"))
ORDER BY [Public Talk Titles].[Talk Number], [Congregation Speaker Talks].congregation;

此查询返回所有会众演讲者谈话号码的列表,其中会众IS 设置为 Keynsham

第 2 步 接下来,我在 Public Talk Titles 表上创建了一个新查询。该表每个通话号码只有一次。我使用KeynshamTalks查询的结果作为子查询:

SELECT *
FROM [Public Talk Titles]
WHERE ((([Public Talk Titles].[Talk Number]) Not In (SELECT [Talk Number]
FROM
[KeynshamTalks]
)))
ORDER BY [Public Talk Titles].[Talk Number];

这行得通。结果正是我想看到的。但是我怎样才能将第一个查询直接移动到第二个查询中,使其成为一个查询呢?

【问题讨论】:

  • 请阅读meta.stackoverflow.com/questions/285551/… 和接受的答案
  • 为什么需要会众名称?
  • @serakfalcon 我不需要它可见。这只是为了发展。我所需要的只是一个唯一的谈话号码列表,其中会众不是 Keynsham。
  • 然后使用 distinct 并删除会众名称。是会众名称导致数字重复且不同。
  • @serakfalcon 如果我删除会众名称,那么我无法将记录过滤到没有 Keynsham 的记录。

标签: sql ms-access


【解决方案1】:

您应该使用NOT EXISTS 而不是NOT IN 编写查询:

SELECT ptt.*
FROM [Public Talk Titles] as ptt
WHERE NOT EXISTS (SELECT 1
                  FROM [Congregation Speaker Talks] as cst
                  WHERE ptt.[Talk Number] = cst.talkno AND
                        cst.congregation = "Keynsham"
                 )
ORDER BY ptt.[Talk Number];

注意表别名(并去掉不需要的括号)如何使查询更易于编写和阅读。

如果您只想要谈话的一个子集,那么在外部查询中添加一个WHERE 子句。

【讨论】:

  • 感谢您的想法。我可以看到它更易于查看,并且我确认它可以在 Access 中使用。在我自己的应用程序中然后失败。但我的其他查询有效。所以我会坚持下去。不过还是谢谢你们。
  • @AndrewTruckle。 . .这个版本也应该更有效率,尤其是使用正确的索引。
  • 由于某种原因,当我使用您的应用程序时,我自己的应用程序没有显示要使用的字段名称。只是 * 和 1。当我使用我的查询时,我会列出“谈话号码”。我将不得不留在我的身边,但我会投票给你。
【解决方案2】:

这就是我想要的:

SELECT *
FROM [Public Talk Titles]
WHERE ((([Public Talk Titles].[Talk Number]) Not In (
SELECT [Public Talk Titles].[Talk Number]
FROM [Public Talk Titles] INNER JOIN [Congregation Speaker Talks] ON [Public Talk Titles].[Talk Number] = [Congregation Speaker Talks].talkno
WHERE ((([Congregation Speaker Talks].congregation)="Keynsham"))
)))
ORDER BY [Public Talk Titles].[Talk Number];

【讨论】:

  • 现在唯一的想法是缺少这个是进一步限制列表,以便显示的最大通话数为 194 或更低。
猜你喜欢
  • 1970-01-01
  • 2010-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-31
相关资源
最近更新 更多