我在一个名为@AccountStatRollup的存储过程中创建了一个表。我使用AccountID填充它。我创建了第二个名为@Contacts的表。我用ContactIDs和ContactAccountIDs填充它。我正在尝试使用@Contacts表中的相关联系人填充@ AccountStatRollup.AccountContacts字段。
我已经尝试了一个数字,如果sql更新语句并失败。这是我试过的最后一句话:
感谢您的帮助。
凯文
Declare @AccountStatRollup TABLE(
AccountID varchar(30),
AccountContacts int
)
Declare @Contacts TABLE(
ContactID varchar(30),
ContactsAccountID varchar(30)
)
我尝试计算帐户联系人计数
UPDATE @AccountStatRollup a
SET a.AccountContacts = (SELECT COUNT(*)FROM @Contacts c GROUP BY c.ContactsAccountID)
ON c.ContactsAccountID = a.ContactID
谢谢大家! 我设法得到这个代码来保存和执行(Microsoft SQL服务器)
--Calculate Account Contacts count
UPDATE @AccountStatRollup
SET AccountContacts = (SELECT COUNT(*) FROM @Contacts
WHERE ContactsAccountID = AccountID )
我让存储过程运行了一段时间然后我就把它杀死了。我意识到这对我来说一定是非常低效的。我将使用此示例添加其他列总计。我可能拥有30,000个帐户和16,000个联系人......
我试图让这段代码正常工作,但它无法识别c.ContactsAccountID,无法绕过它。
--Calculate Account Contacts count ver 2
UPDATE a
SET AccountContacts = c.cnt
FROM @AccountStatRollup a join
(SELECT COUNT(*) as cnt
FROM @Contacts c
GROUP BY c.ContactsAccountID
) c
ON c.ContactsAccountID = a.AccountID;
Msg 207,Level 16,State 1,Procedure AccountStatRollup,56行 列名称“ContactsAccountID”无效。
有没有比我尝试的更有效的计算总数的方法?
谢谢!
好的,我想出了如何快速完成这项工作。
我使用唯一索引创建了临时表。
- 创建一个本地表来保存帐户统计信息 声明@AccountStatRollup TABLE( AccountID varchar(18), AccountContacts int, 独特(AccountID) );
- 创建一个本地表来保存联系人数据 声明@Contacts TABLE( ContactID varchar(18), ContactsAccountID varchar(18), 独特(ContactID) );
- 创建一个本地表来保存联系人计算数据 声明@tmpAccountCalculation TABLE( AccountID varchar(18), AccountName varchar(100), FieldCount int, 独特(AccountID) );
- 使用所有AccountID值填充@AccountStatRollup表 INSERT INTO @AccountStatRollup(AccountID) 来自sfAccount的SELECT ID - 使用所有AccountID值填充@Contacts表 INSERT INTO @Contacts(ContactID,ContactsAccountID) 来自sfContact的SELECT ID,ACCOUNTID
- 填充@tmpAccountCalculation表 INSERT INTO @tmpAccountCalculation(AccountID,AccountName,FieldCount) SELECT dbo.sfAccount.ID,dbo.sfAccount.NAME,COUNT(dbo.sfContact.ACCOUNTID)AS ContactCount FROM dbo.sfAccount INNER JOIN dbo.sfContact ON dbo.sfAccount.ID = dbo.sfContact.ACCOUNTID GROUP BY dbo.sfAccount.ID,dbo.sfAccount.NAME HAVING(COUNT(dbo.sfContact.ACCOUNTID)> 0)
- 更新@AccountStatRollup表 更新A. SET A.AccountContacts = B.FieldCount 来自@AccountStatRollup A. INNER JOIN @tmpAccountCalculation B ON A.AccountID = B.AccountID
- 测试输出 从@AccountStatRollup中选择*,其中AccountContacts> 0按AccountContacts desc排序
这需要大约1秒才能运行。
...呼
凯文
答案 0 :(得分:1)
您应该将where条件移动到内部查询,并且不需要该组:
UPDATE @AccountStatRollup a
SET
a.AccountContacts = (
SELECT
COUNT(*)
FROM
@Contacts c
where
c.ContactsAccountID = a.ContactID
);
答案 1 :(得分:0)
因为您正在使用表变量,所以我假设这是SQL Server。您可以使用update
join
语法:
UPDATE a
SET AccountContacts = c.cnt
FROM @AccountStatRollup a join
(SELECT COUNT(*) as cnt
FROM @Contacts c
GROUP BY c.ContactsAccountID
) c
ON c.ContactsAccountID = a.ContactID;
SQL标准方法应该在几乎所有数据库中都可以使用相关子查询:
UPDATE @AccountStatRollup a
SET AccountContacts = (SELECT COUNT(*)
FROM @Contacts c
WHERE c.ContactsAccountID = a.ContactID
);
使用相关子查询时,不需要group by
。实际上,包含group by
会产生误导,因为它表明可能存在多个组 - 并且在执行语句时会导致错误。