我可能以错误的方式做到这一点......但这就是我所拥有的......这是一个带有数据模型的Oracle实例:
TABLE 1
-----------
ID | NAME |
-----------
TABLE 2
----------------------------------------------
ID | NAME | TABLE_1_ID | TIMESTAMP | SOME_NUM
----------------------------------------------
TABLE 3
-----------------------
ID | NAME | TABLE_1_ID
-----------------------
我想要一个给我4列的查询:
我希望表1与其他两个表相比较小。
以下是我为生成前两组所做的工作:
select t1.name, a.count
from
( select TABLE_1_ID, COUNT(*) count
from TABLE_2
group by TABLE_1_ID
) a,
table_1 t1
where t1.id = a.table_1_id
这很有用......但是当我试图获得第三列时,这就失败了。
select t1.name, a.count, b.count2
from
( select TABLE_1_ID, COUNT(*) count
from TABLE_2
group by TABLE_1_ID
) a,
( select TABLE_1_ID, COUNT(*) count2
from TABLE_2
where TIMESTAMP < ? and TIMESTAMP > ?
group by TABLE_1_ID
) b,
table_1 t1
where t1.id = a.table_1_id and t1.id = b.table_1_id
这不会返回任何不满足有关时间戳的where子句的条目。如果我改变了和一个或者,我会重复t1.names。
我不太擅长SQL,你可以说。我认为它在这里进行内连接,但我想我想要一个外连接,因为我想要一个与TABLE_1具有相同行数的结果集。在理解如何正确获得第三个结果之前,我甚至不想尝试第四个结果。
答案 0 :(得分:2)
试试这个:
SELECT t1.NAME,
SUM(CASE
WHEN t2.some_num = 1 THEN 1
ELSE 0
END),
SUM(CASE
WHEN t2.timestamp BETWEEN SYSDATE-1 AND SYSDATE+1 THEN 1
ELSE 0
END),
t3.cnt
FROM table1 t1
LEFT JOIN table2 t2 ON t1.ID = t2.table_1_id
LEFT JOIN (SELECT table_1_id,
COUNT(1) cnt
FROM table3
GROUP BY table_1_id) t3 ON t1.id = t3.table_1_id
GROUP BY t1.name
答案 1 :(得分:0)
而不是JOIN,只需将它们显示为为列提供标量值的子查询。
即。最多第3列
select
t1.name,
( select COUNT(*)
from TABLE_2 a
WHERE a.TABLE_1_ID = t1.ID
) a_count,
( select COUNT(*)
from TABLE_2 b
where b.TIMESTAMP < ? and b.TIMESTAMP > ?
AND t1.id = b.table_1_id
) b_count
from table_1 t1
这需要N x C子选择,t1中每行对应一列。
如果表不是太大,或者每个子查询在table_1_id上都有一个好的索引,那么合理地工作,这样子查询总访问量就不会超过全表扫描的行数。请记住,count(*)查询可以直接从索引页面满足,而无需查找实际的表数据,因此它非常快。
对所涉及的每个表执行单次传递,并将它们连接在一起。
select t1.name, nvl(a.count1,0) count1, nvl(b.count2,0) count2
from table_1 t1
left join
( select TABLE_1_ID, COUNT(*) count1
from TABLE_2
group by TABLE_1_ID
) a ON t1.id = a.table_1_id
left join
( select TABLE_1_ID, COUNT(*) count2
from TABLE_2
where TIMESTAMP < ? and TIMESTAMP > ?
group by TABLE_1_ID
) b ON t1.id = b.table_1_id
左连接子选择(按TABLE_1_ID分组)确保TABLE1.ID为1行,或者没有行。这可以防止笛卡尔产品的出现。现在您可以获取计数,但添加了NVL
,因为在此表单中,count可能会返回为NULL。
在显示的第一种形式中,count永远不会为NULL。