获取多个表的每个租户的行数
Get the number of rows per tenant of several tables
假设我有 2 个 table: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
现在,假设我有另一个 table,Fiddles
,因为 Wargles
对 Tenants
有 FK。我如何在上面的查询中添加另一列,以便获得每个租户的 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 提供相同的数字,即来自 tables.
的行的乘积
最有效的方法可能是使用相关子查询:
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)
上的索引。
使用两个子选择
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
对于您的情况,作为可扩展的解决方案,我建议使用标量函数。
/* 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声明
SELECT Id AS TenantId
,dbo.ufnGetTenantsNo(Id, 1) AS WargleCount
,dbo.ufnGetTenantsNo(Id, 2) AS FiddleCount
FROM Tenants
假设我有 2 个 table: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
现在,假设我有另一个 table,Fiddles
,因为 Wargles
对 Tenants
有 FK。我如何在上面的查询中添加另一列,以便获得每个租户的 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 提供相同的数字,即来自 tables.
的行的乘积最有效的方法可能是使用相关子查询:
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)
上的索引。
使用两个子选择
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
对于您的情况,作为可扩展的解决方案,我建议使用标量函数。
/* 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声明
SELECT Id AS TenantId
,dbo.ufnGetTenantsNo(Id, 1) AS WargleCount
,dbo.ufnGetTenantsNo(Id, 2) AS FiddleCount
FROM Tenants