比如说我有2张桌子。Tenants
和 Wargles
. Wargles
有一个外键向 Tenants
叫做 TenantId
. 如果我想知道每个租户的Wargles数量,我可以这样做。
SELECT t.Id as TenantId, count(w.Id) as WargleCount
FROM Tenants t
JOIN Wargles w ON w.TenantId = t.Id
GROUP BY t.Id
现在,让我们假设我有另一张表。Fiddles
,因为 Wargles
有一个FK走向 Tenants
. 我怎样才能在上面的查询中再加一列,这样我就能得到每个租户的wargles数和fiddles数?
我试过用这个方法。
SELECT t.Id as TenantId, count(w.Id) as WargleCount, count(f.Id) as FiddleCount
FROM Tenants t
JOIN Wargles w ON w.TenantId = t.Id
JOIN Fiddles f ON f.TenantId = t.Id
GROUP BY t.Id
但这行不通 因为WargleCount和FiddleCount的数字是一样的 是两张表的行的乘积
使用两个子选择
SELECT t.Id as TenantId,
(SELECT Count(1) FROM Fiddles F WHERE F.TenantId = T.Id) as FiddleCount,
(SELECT Count(1) FROM Wargles W WHERE W.TenantId = T.Id) as WargleCount
FROM Tenants t
最有效的方法可能是使用相关的子查询。
SELECT t.Id as TenantId,
(SELECT COUNT(*)
FROM Wargles w
WHERE w.TenantId = t.Id
) as WargleCount, count(f.Id) as FiddleCount
(SELECT COUNT(*)
FROM Fiddles f
WHERE f.TenantId = t.Id
) as FiddleCount
FROM Tenants t;
特别是,这可以利用关于以下方面的索引: Wargles(TenantId)
和 Fiddles(TenantId)
.
在你的情况下,作为可扩展的解决方案,我建议使用Scalar Function。
/* SAMPLE DATA ARRANGE */
CREATE TABLE Tenants (Id INT, Title NVARCHAR(5)) ; INSERT INTO Tenants VALUES (1, 'A'), (2, 'B') , (3, 'C');
CREATE TABLE Wargles (Id INT,TenantId INT);INSERT INTO Wargles VALUES (1, 1), (2, 1) , (3, 1) , (4, 2), (5, 2) , (6, 1), (7, 3) , (8, 3);
CREATE TABLE Fiddles (Id INT,TenantId INT);INSERT INTO Fiddles VALUES (1, 1), (2, 1) , (3, 1) , (4, 2), (5, 2) , (6, 2), (7, 3) , (8, 2);
函数
/*NEEDED CODE*/
CREATE FUNCTION dbo.ufnGetTenantsNo ( @Id AS INT , @Tb AS INT)
RETURNS INT
AS
BEGIN
DECLARE @Result INT = 0;
IF (@TB = 1)
SELECT @Result = COUNT(*)
FROM Wargles
WHERE TenantId = @Id
ELSE
SELECT @Result = COUNT(*)
FROM Fiddles
WHERE TenantId = @Id
RETURN @Result
END
GO
选择声明
SELECT Id AS TenantId
,dbo.ufnGetTenantsNo(Id, 1) AS WargleCount
,dbo.ufnGetTenantsNo(Id, 2) AS FiddleCount
FROM Tenants