当前位置: 首页 > 知识库问答 >
问题:

对一个联接使用第一个结果在第二个结果(子查询)来获取所有行的一个查询

韩安顺
2023-03-14

所以我在这个问题上纠结了一段时间。 虽然我确实可以对这个问题进行两个单独的查询,但我想知道是否可以进行一个查询。 我认为一个SQL专业人士肯定知道如何做到这一点。 所以事情是这样的:

我们有两个表posts和post_translations。 为简单起见缩写。

posts
------
id

post_translations
-----------------
id
post_id (which is the FK on posts...)
locale
slug
content
... (and so on)

很明显,我现在可以做一个非常简单的内部连接,把所有的帖子翻译成一种特定的语言,我们可以说'en'或'de',如果你想的话。 所以我不会再为这事打扰你了。

但由于表还将包含子区域设置,如en(美国),en-GB,en-AU,de(德国),de-AT,de-CH.。。。 随着Szenario的到来,整个事情变得更加复杂。

假设有些帖子只翻译成“de”,也有翻译成“de-at”的。 该表将如下所示:

post_translations
id    post_id   locale    content
1        1       de         ...
2        1       de-AT      ...
3        2       de         ...

所以post 1在“de”和“de-at”中可用。 岗位2仅在“de-at”中可用。

如果我想把所有的帖子都放在“de”里,那就很容易了。 我只需要添加一个WHERE locale='de'就可以了。 但是,假设我希望所有的帖子都在'de-at'中,所有其他的帖子都在'de'中,但没有翻译成'de-at',这样我就不会得到任何重复的内容--我如何在一个查询中实现这一点呢? 如前所述,我可以在这里运行两个查询,首先在'de-at'中获取所有的post,然后在'de'中获取所有的post,并使用我从第一个查询中获得的'post_id'和一个WHERE not in query,这样我就不会得到任何重复。

这些询问将是:

SELECT 
    pt.post_id
FROM
    posts AS p
        INNER JOIN
    post_translations AS pt ON p.id = pt.post_id
WHERE
    pt.locale = 'de-AT';

在此查询中,您将使用post_id:

SELECT 
    *
FROM
    posts AS p
        INNER JOIN
    post_translations AS pt ON p.id = pt.post_id
WHERE
    pt.locale = 'de' AND pt.post_id NOT IN (*post_ids found in first search*);

查询背后的思想是显示一个地区的特定帖子,在本例中是“de-at”,但也显示为“de”用户编写的一般帖子。

我希望这说得通。 如果你能帮上忙,我会很感激的。 谢谢。

共有2个答案

翟鸿振
2023-03-14

显示一个地区的特定帖子,在本例中为“de-at”,但也显示为“de”用户编写的一般帖子

我相信简单的where子句和运算符in将返回预期的结果。
然后,您可以使用条件聚合标记具有所需的子区域设置的帖子,并可能首先对这些帖子进行排序:

SELECT post_id, 
       MAX(locale = 'de-AT') AS flag
FROM post_translations 
WHERE locale IN ('de', 'de-AT')
GROUP BY post_id
ORDER BY flag DESC

您可以将上述查询连接到posts以获取每个post的详细信息:

SELECT p.*, t.flag
FROM posts AS p INNER JOIN (
    SELECT post_id, 
           MAX(locale = 'de-AT') AS flag
    FROM post_translations 
    WHERE locale IN ('de', 'de-AT')
    GROUP BY post_id
) t ON t.post_id = p.id
ORDER BY t.flag DESC
阎坚成
2023-03-14

一个选项使用不存在:

select pt.*
from post_translations pt
where 
    locale = 'de-AT'
    or (
        locale = 'de'
        and not exists (
            select 1 
            from post_translations pt1
            where pt1.post_id = pt.post_id and pt1.locale = 'de-AT'
        )
    )
    

或者,如果您正在运行MySQL8.0,也可以使用row_number():

select *
from (
    select 
        pt.*, 
        row_number() over(partition by post_id order by (locale = 'de')) rn
    from post_translations pt
    where locale in ('de', 'de-AT')
) pt
where rn = 1

您可以轻松地将上述查询修改为joinposts表。

 类似资料:
  • 问题内容: 我有一个查询。现在,此查询当然返回一个结果集,我想要的是查询此查询的结果集,例如,我只希望上述查询具有唯一的名称。我应该提一下,我知道我可以在Query1中使用,但这只是一个示例,我的实际情况有些不同,我想知道的是是否可以查询上一个查询的结果集。我正在使用SQL Server 2012。 问题答案: 您可以使用该子句

  • 我有两个表TABLE_A,列名为COLUMN1 COLUMN2 COLUMN3 COLUMN 4 COLUM5 abc def ghi jkl mno 123 456 789 001 121 TABLE_B列名为COLUMN6 COLUMN7,其数据为 专栏5 124 第4列bca 第3列aaa 列5 BBB 所以我将Table_A的列名作为Table_B中的数据 所以我想在一个查询中做这样的事情

  • 问题内容: 我试图加快PHP脚本的速度,目前正在Mysql域中推送一些PHP逻辑。如果第一个Select不返回行或计数为零,是否可以进行其他选择查询? 请记住,第一个查询需要首先运行,并且 仅 当第一个查询返回空集 时才 应激活第二个查询。 对于上面的2个查询,我有这段代码,但似乎每个查询运行两次(一次计数,一次返回)。有一个更好的方法吗? 问题答案: 一种选择是使用有: SQL小提琴演示 这将从

  • 我正在尝试加速一个PHP脚本,目前我正在推动一些PHP逻辑在Mysql领域的东西。如果第一个select没有返回行或计数为零,是否有方法进行不同的select查询? 请记住,需要首先运行第一个查询,只有在第一个查询返回一个空集时才应激活第二个查询。 对于上面的2个查询,我有这段代码,但它似乎要运行每个查询两次(一次用于计数,一次用于返回)。有没有更好的办法做到这一点?

  • 我的SQL有这些表: ___BookingsDatas ___预订 _ _ _客户 我想链接这些表,所以我有这个查询: 它实际上起作用了。 问题是在第二个表上,我有一些信息需要与第三个表链接。 例如,我需要有以下结果: 那么,在这种情况下,如何在另一个where语句中使用第一个mysql查询的结果? 谢谢。

  • 在阅读了Oracle站点上的这篇文章https://community.Oracle.com/docs/doc-995305之后,我将尝试实现“Some Two-to-One selection patterns”段落中描述的模式。这最后一类模式还包含二对一模式。但是这次不是执行一次下游元素,而是完成两个上游元素,当两个上游元素中的一个完成时执行下游元素。例如,当我们要解析域名时,这可能会证明非常

  • 我有用于分页的逻辑,它工作得非常好。这个问题是为了优化/改进我是如何做某事的。 我正在运行两个查询以获得结果集。第一个查询按限制和偏移量获取所有项,第二个查询获取总计数。我需要这个总数来计算表示层中的分页链接。 我想避免运行两个查询,如果可能的话,将它们合并成一个。 例如,如果数据库中有100项,并且我运行下面的查询时为1,为20,那么查询应该返回20个结果和100个计数。我目前在两个单独的查询中