【问题标题】:SQL Get Count Across 3 TablesSQL 获取 3 个表的计数
【发布时间】:2021-03-03 08:52:34
【问题描述】:

我有 3 张桌子,一张有这两列

table1:

id, name
0   foo
1   etc
2   example

table2:
id  table1_id
0       1
1       0
2       2

table3:
id  table2_id
 0     1
 1     0
 2     0

哪个查询可以从 table1 中找到所有“名称”,其中 table2 中的所有 id 在 table3 中的计数至少为 n?即如果 n 为 1 它应该返回 foo 等

编辑:

解释得很糟糕,我试图获取 table1 中每条记录的名称,其中 table2 中的所有对应记录(即 table1_ID 列等于 table1 中的每个 id 的记录。在我的示例表中,每个 ID 都有一个)在 table3 中至少有 n 个计数。

如果 n 为 1,因为 table2_id 0 在记录 1 和 2 中出现两次,将返回其“父级”。它对应于表 1 记录 1,因此应该返回具有 table1 id: 1 的记录的名称,即等。示例也因为它在底部列中的计数为 1,但是 foo 没有出现,所以它不应该. 预期结果:

name
foo
etc

【问题讨论】:

  • 样本数据很好,但您也应该指定预期结果。
  • 还向我们展示您当前的查询尝试。
  • 已编辑,我没有当前的查询尝试,因为我不确定要尝试什么。

标签: sql database sqlite


【解决方案1】:

您可以使用where 子句中的子查询来做到这一点:

select t1.*
from table1 t1
where (select count(t3.id)
       from table2 t2 left join
            table3 t3
            on t3.table2_id = t2.id
       where t2.table1_id = t1.id
       group by t2.id
       order by count(*) asc -- to get the minimum
       limit 1
      ) >= ?  -- value you care about

我怀疑这可能具有适当索引的最佳性能:table2(table1_id, id)table3(table2_id)

【讨论】:

【解决方案2】:

如果我理解了这个问题 - 如果对 table3.table2_id 的检查大于 0,那么答案会是“等”吗? 代码如下

select t1.name
from 
(
 select 0 as id, 1 as table2_id 
 union select 1, 0
 union select 2 , 0
) t3

inner join 
(
select 0 as id ,  1 as table_id
union select 1, 0
union select 2, 2
) t2 on t2.table_id = t3.table2_id
inner join 
(
select 0 as id,  'foo' as name 
union select 1   , 'etc'
union select 2   , 'example'
) t1 on t1.id = t2.table_id
 where t3.table2_id > 0

【讨论】:

【解决方案3】:
select table1.name 
FROM table1 
INNER JOIN table2 ON table1.id=table2.table1_id
INNER JOIN table3 ON table2.id=table3.table2_id
GROUP BY table1.name 
HAVING count(*) >= 1 

用你想要的n替换最后一个1

这里是 sql fiddle 如果你想玩它:http://sqlfiddle.com/#!7/14217/4

【讨论】:

  • 不适用于这种情况:dbfiddle.uk/…
  • 我同意您的查询以不同的方式实现逻辑。我会让海报决定它是否适合他的需要。这一切都取决于你如何解释ALL corresponding records have count of at least n。您将ALL 解释为each one of them。我将其解释为将它们视为一个整体。
【解决方案4】:

使用INNERtable1 连接到table2,然后将LEFT 连接到table3 并计算table3 对应的ids。
然后通过第二级聚合仅返回 table1 的行,其中所有计数器至少为 1

SELECT id, name
FROM (
  SELECT t1.id, t1.name, COUNT(t3.id) counter 
  FROM table1 t1
  INNER JOIN table2 t2 ON t2.table1_id = t1.id
  LEFT JOIN table3 t3 ON t3.table2_id = t2.id
  GROUP BY t1.id, t1.name, t2.id
)
GROUP BY id, name
HAVING MIN(counter) >= 1 -- change to the number that you want 

请参阅demo
结果:

id name
0 foo
1 etc

【讨论】:

    猜你喜欢
    • 2013-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-18
    • 2017-01-01
    相关资源
    最近更新 更多