对另一个 table 的每一行循环相同的查询
Loop the same query for every row of another table
我正在尝试为不同 table 中的每一行获取循环结果。我需要知道哪个产品线,每个销售代理,在一个月内销售。
我的查询告诉我如何知道产品线的总数。我只需要在其中插入 where 条件中的 "CODAGENT",循环遍历 Agents TABLE 中的每个代理。所以举个例子,不用 sql 语言。
-----THIS IS NOT A USEFUL CODE, IT'S ONLY FOR UNDERSTANDING----
For Each Row in Agents TAble Do
Set #CODAGENT = Row 1,2,3,....
Select
-routine for selecting what i need with inside WHERE CODAGENT = #CODAGENT
Next Row
-----THIS IS NOT A USEFUL CODE, IT'S ONLY FOR UNDERSTANDING----
我需要获得此结果,但每个代理 table
SELECT
TABCATEGORIE.DESCRIZIONE,
TABCATEGORIESTAT.DESCRIZIONE,
LEFT(SUM(TOTNETTORIGA),LEN(SUM(TOTNETTORIGA))-2),
TABGRUPPI.DESCRIZIONE,
ANAGRAFICAAGENTI.CODAGENTE,
ANAGRAFICAAGENTI.DSCAGENTE
FROM dbo.TESTEDOCUMENTI
INNER JOIN dbo.RIGHEDOCUMENTI ON PROGRESSIVO=IDTESTA
INNER JOIN dbo.ANAGRAFICAARTICOLI
ON CODART=ANAGRAFICAARTICOLI.CODICE
INNER JOIN dbo.TABCATEGORIE ON CATEGORIA=TABCATEGORIE.CODICE
INNER JOIN dbo.TABCATEGORIESTAT ON CODCATEGORIASTAT=TABCATEGORIESTAT.CODICE
INNER JOIN dbo.TABGRUPPI ON GRUPPO=TABGRUPPI.CODICE
INNER JOIN dbo.ANAGRAFICAAGENTI ON ANAGRAFICAAGENTI.CODAGENTE=CODAGENTE1
WHERE dbo.TESTEDOCUMENTI.DOCCHIUSO = '0' AND dbo.TESTEDOCUMENTI.TIPODOC = 'FVC' AND dbo.TESTEDOCUMENTI.DATADOC BETWEEN DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())-2, 0) AND DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE())-2, -1)
GROUP BY GRUPPO,CATEGORIA,CODCATEGORIASTAT,TABCATEGORIE.DESCRIZIONE,TABCATEGORIESTAT.DESCRIZIONE,TABGRUPPI.DESCRIZIONE,ANAGRAFICAAGENTI.CODAGENTE,ANAGRAFICAAGENTI.DSCAGENTE
ORDER BY CODAGENTE DESC
是意大利语,不知道你看懂没有
Sample Data
ANAGRAFICAAGENTI
CODAGENTE | DSCAGENTE
A1 | Agent Name
then there is the result of the query. So The result is
CATEGORY | CATEGORY2 |TOTNETTORIGA| GRUPPI | CODAGENTE | DSCAGENTE
------------+---------------+------------+------------------+-----------+----------
TAVOLI | TAVOLI | 22571.36 | PRODOTTO FINITO | A 77 | name
PENSILI | PENSILI | 1319.12 | PRODOTTO FINITO | A 77 | name
LAVATOIO | LAVATOIO | 7411.08 | PRODOTTO FINITO | A 77 | name
LAVATOIO | MACELLERIA | 505.00 | PRODOTTO FINITO | A 77 | name
MACELLERIA | MACELLERIA | 3762.00 | PRODOTTO FINITO | A 77 | name
LINEA PESCE | LINEA PESCE | 3824.00 | PRODOTTO FINITO | A 77 | name
TAVOLI | TAVOLI | 1073.60 | PRODOTTO FINITO | A 76 | name1
PENSILI | PENSILI | 262.80 | PRODOTTO FINITO | A 76 | name1
已达到此新步骤以实现我的目标,但仍然无效。这是我的查询:
---CREO IL CURSORE C PER CALCOLARE GLI AGENTI---
DECLARE c CURSOR FOR
SELECT DISTINCT
ANAGRAFICAAGENTI.CODAGENTE
FROM dbo.ANAGRAFICAAGENTI
----DICHIARO LA VARIABILE PER AGENTE
DECLARE @AgentID VARCHAR(4)
----PRENDI IL PRIMO AGENTE E METTILO NELLA VARIABILE----
OPEN c
FETCH NEXT FROM c INTO @AgentID
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT
ANAGRAFICAAGENTI.DSCAGENTE,
ANAGRAFICAAGENTI.CODAGENTE,
TABCATEGORIE.DESCRIZIONE,
TABCATEGORIESTAT.DESCRIZIONE,
LEFT(SUM(TOTNETTORIGA),LEN(SUM(TOTNETTORIGA))-2),
TABGRUPPI.DESCRIZIONE
FROM dbo.TESTEDOCUMENTI
INNER JOIN dbo.RIGHEDOCUMENTI ON PROGRESSIVO=IDTESTA
INNER JOIN dbo.ANAGRAFICAARTICOLI
ON CODART=ANAGRAFICAARTICOLI.CODICE
INNER JOIN dbo.TABCATEGORIE ON CATEGORIA=TABCATEGORIE.CODICE
INNER JOIN dbo.TABCATEGORIESTAT ON CODCATEGORIASTAT=TABCATEGORIESTAT.CODICE
INNER JOIN dbo.TABGRUPPI ON GRUPPO=TABGRUPPI.CODICE
LEFT JOIN dbo.ANAGRAFICAAGENTI ON ANAGRAFICAAGENTI.CODAGENTE=CODAGENTE1
WHERE ANAGRAFICAAGENTI.CODAGENTE = @AgentID AND dbo.TESTEDOCUMENTI.DOCCHIUSO = '0' AND dbo.TESTEDOCUMENTI.TIPODOC = 'FVC' AND dbo.TESTEDOCUMENTI.DATADOC BETWEEN DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())-2, 0) AND DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE())-2, -1)
GROUP BY GRUPPO,CATEGORIA,CODCATEGORIASTAT,TABCATEGORIE.DESCRIZIONE,TABCATEGORIESTAT.DESCRIZIONE,TABGRUPPI.DESCRIZIONE,ANAGRAFICAAGENTI.CODAGENTE,ANAGRAFICAAGENTI.DSCAGENTE
ORDER BY CODAGENTE DESC,SUM(TOTNETTORIGA) desc
--PRENDI IL PROSSIMO AGENTE---
FETCH NEXT FROM c INTO @AgentID
END
--PULISCI---
CLOSE c
DEALLOCATE c
这让我有不同的 table,我想 table 中的每个代理都有一个。但它们都是空的。如果我在 WHERE 条件下删除 ANAGRAFICAAGENTI.CODAGENTE = @AgentID,我会得到相同的 table 但每个结果都相同。他们都是平等的。
SQL 最适合基于集合的操作,但是针对您的情况使用循环的一种方法是使用 CURSOR
和 FETCH
。您需要研究这些并将其正确应用于您的数据,特别是因为您说 "obtain this result but in separate table"。我不知道您是想插入新的 table 还是 return 单独的 window 窗格中的结果。这将帮助您入门
--declare a cursor which will be the ID's of your agents. You can use what ever you want to limit your data off of
DECLARE c CURSOR FOR
SELECT DISTINCT
CODAGENTE
FROM ANAGRAFICAAGENTI
DECLARE @AgentID VARCHAR(4)
--get the first agent id and place it into a variable
OPEN c
FETCH NEXT FROM c INTO @AgentID
--for each agent id, select some data where the agent id equals the current agent id in the cursor
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT
--put your code here for selecting, inserting into a table, etc
WHERE ANAGRAFICAAGENTI.CODAGENTE = @AgentID --or what ever is appropiate
--get the next agent
FETCH NEXT FROM c INTO @AgentID
END
--clean up
CLOSE c
DEALLOCATE c
为了加分,我建议您开始在代码中使用 table 别名。它将使您和其他人在未来更加清晰易读。
https://technet.microsoft.com/en-us/library/ms187455(v=sql.105).aspx
SQL Table Aliases - Good or Bad?
样本集
点击HERE到运行下面的代码...
IF OBJECT_ID('tempdb..#agents') IS NOT NULL DROP TABLE #agents
IF OBJECT_ID('tempdb..#items') IS NOT NULL DROP TABLE #items
create table #agents (AgentID varchar(2), name varchar(50))
insert into #agents values
('A1','Julius Cesar'),
('B2','Albert Einstien')
create table #items (AgentID varchar(2), ItemID int, ItemName varchar(50))
insert into #items (AgentID, ItemID, ItemName) values
('A1',1,'Apple'),
('A1',2,'Pear'),
('A1',3,'Watermelon'),
('A1',4,'Grape'),
('B2',5,'Car'),
('B2',6,'Truck'),
('B2',7,'Van')
DECLARE c CURSOR FOR
SELECT DISTINCT
AgentID
FROM #agents
DECLARE @AgentID VARCHAR(4)
--get the first agent id and place it into a variable
OPEN c
FETCH NEXT FROM c INTO @AgentID
--for each agent id, select some data where the agent id equals the current agent id in the cursor
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT
AgentID, ItemID, ItemName
FROM #items
WHERE AgentID = @AgentID --or what ever is appropiate
--get the next agent
FETCH NEXT FROM c INTO @AgentID
END
--clean up
CLOSE c
DEALLOCATE c
如果我没有正确理解你的问题,那么我认为你可以使用 cross apply
运算符。
为了说明我的意思,让我们查找一些示例数据。一开始我声明了三个临时的tables用于代理,产品和交易这样
declare @Agents table (AgentId int, AgentName nvarchar(max));
declare @Products table (ProductId int, ProductName nvarchar(max), Price money);
declare @Transactions table (TransactionId int, TransactionDate date, AgentId int, ProductId int, Quantity int);
然后我用这样的示例数据填充 tables
insert into @Agents
values (1, N'Agnet1'), (2, N'Agent2'), (3, N'Agent3'), (4, N'Agent4');
insert into @Products
values (1, N'Product1', 100), (2, N'Product2', 150.50), (3, N'Product3', 200), (4, N'Product4', 50.23);
insert into @Transactions
values (1, '20160604', 1, 1, 5), (2, '20160704', 2, 1, 10), (3,'20160612', 2, 1, 15), (4, '20160604', 1, 2, 7),
(5, '20160720', 3, 4, 1), (6, '20160604', 2, 4, 3), (7, '20160730', 4, 3, 8), (8, '20160612', 2, 3, 13),
(9, '20160708', 4, 2, 6), (10, '20160705', 1, 3, 1), (11, '20160616', 4, 2, 17), (12, '20160709', 2, 3, 13);
使用该示例数据,我准备了此查询以获取每个代理的统计信息
declare @year int;
declare @month int;
select a.AgentName,
trans.ProductName,
trans.Amount
from @Agents as a
cross apply
( select t.ProductId,
max(p.ProductName) as ProductName,
sum(t.Quantity * p.Price) as Amount
from @Transactions as t
inner join @Products as p on p.ProductId = t.ProductId
where t.AgentId = a.AgentId
and year(t.TransactionDate) = @year
and month(t.TransactionDate) = @month
group by t.ProductId) as trans
对于输出上的 @year = 2016
和 @month = 6
你可以看到这个
AgentName ProductName Amount
Agnet1 Product1 500,00
Agnet1 Product2 1053,50
Agent2 Product1 1500,00
Agent2 Product3 2600,00
Agent2 Product4 150,69
Agent4 Product2 2558,50
对于 @year = 2016
和 @month = 7
你会看到这个
AgentName ProductName Amount
Agnet1 Product3 200,00
Agent2 Product1 1000,00
Agent2 Product3 2600,00
Agent3 Product4 50,23
Agent4 Product2 903,00
Agent4 Product3 1600,00
如您所见,我要求每个代理表单 @Agents
table 并且我对每个代理执行额外的查询,从 [=21= 中检索有关产品和总金额的数据] table.
我正在尝试为不同 table 中的每一行获取循环结果。我需要知道哪个产品线,每个销售代理,在一个月内销售。
我的查询告诉我如何知道产品线的总数。我只需要在其中插入 where 条件中的 "CODAGENT",循环遍历 Agents TABLE 中的每个代理。所以举个例子,不用 sql 语言。
-----THIS IS NOT A USEFUL CODE, IT'S ONLY FOR UNDERSTANDING----
For Each Row in Agents TAble Do
Set #CODAGENT = Row 1,2,3,....
Select
-routine for selecting what i need with inside WHERE CODAGENT = #CODAGENT
Next Row
-----THIS IS NOT A USEFUL CODE, IT'S ONLY FOR UNDERSTANDING----
我需要获得此结果,但每个代理 table
SELECT
TABCATEGORIE.DESCRIZIONE,
TABCATEGORIESTAT.DESCRIZIONE,
LEFT(SUM(TOTNETTORIGA),LEN(SUM(TOTNETTORIGA))-2),
TABGRUPPI.DESCRIZIONE,
ANAGRAFICAAGENTI.CODAGENTE,
ANAGRAFICAAGENTI.DSCAGENTE
FROM dbo.TESTEDOCUMENTI
INNER JOIN dbo.RIGHEDOCUMENTI ON PROGRESSIVO=IDTESTA
INNER JOIN dbo.ANAGRAFICAARTICOLI
ON CODART=ANAGRAFICAARTICOLI.CODICE
INNER JOIN dbo.TABCATEGORIE ON CATEGORIA=TABCATEGORIE.CODICE
INNER JOIN dbo.TABCATEGORIESTAT ON CODCATEGORIASTAT=TABCATEGORIESTAT.CODICE
INNER JOIN dbo.TABGRUPPI ON GRUPPO=TABGRUPPI.CODICE
INNER JOIN dbo.ANAGRAFICAAGENTI ON ANAGRAFICAAGENTI.CODAGENTE=CODAGENTE1
WHERE dbo.TESTEDOCUMENTI.DOCCHIUSO = '0' AND dbo.TESTEDOCUMENTI.TIPODOC = 'FVC' AND dbo.TESTEDOCUMENTI.DATADOC BETWEEN DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())-2, 0) AND DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE())-2, -1)
GROUP BY GRUPPO,CATEGORIA,CODCATEGORIASTAT,TABCATEGORIE.DESCRIZIONE,TABCATEGORIESTAT.DESCRIZIONE,TABGRUPPI.DESCRIZIONE,ANAGRAFICAAGENTI.CODAGENTE,ANAGRAFICAAGENTI.DSCAGENTE
ORDER BY CODAGENTE DESC
是意大利语,不知道你看懂没有
Sample Data
ANAGRAFICAAGENTI
CODAGENTE | DSCAGENTE
A1 | Agent Name
then there is the result of the query. So The result is
CATEGORY | CATEGORY2 |TOTNETTORIGA| GRUPPI | CODAGENTE | DSCAGENTE
------------+---------------+------------+------------------+-----------+----------
TAVOLI | TAVOLI | 22571.36 | PRODOTTO FINITO | A 77 | name
PENSILI | PENSILI | 1319.12 | PRODOTTO FINITO | A 77 | name
LAVATOIO | LAVATOIO | 7411.08 | PRODOTTO FINITO | A 77 | name
LAVATOIO | MACELLERIA | 505.00 | PRODOTTO FINITO | A 77 | name
MACELLERIA | MACELLERIA | 3762.00 | PRODOTTO FINITO | A 77 | name
LINEA PESCE | LINEA PESCE | 3824.00 | PRODOTTO FINITO | A 77 | name
TAVOLI | TAVOLI | 1073.60 | PRODOTTO FINITO | A 76 | name1
PENSILI | PENSILI | 262.80 | PRODOTTO FINITO | A 76 | name1
已达到此新步骤以实现我的目标,但仍然无效。这是我的查询:
---CREO IL CURSORE C PER CALCOLARE GLI AGENTI---
DECLARE c CURSOR FOR
SELECT DISTINCT
ANAGRAFICAAGENTI.CODAGENTE
FROM dbo.ANAGRAFICAAGENTI
----DICHIARO LA VARIABILE PER AGENTE
DECLARE @AgentID VARCHAR(4)
----PRENDI IL PRIMO AGENTE E METTILO NELLA VARIABILE----
OPEN c
FETCH NEXT FROM c INTO @AgentID
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT
ANAGRAFICAAGENTI.DSCAGENTE,
ANAGRAFICAAGENTI.CODAGENTE,
TABCATEGORIE.DESCRIZIONE,
TABCATEGORIESTAT.DESCRIZIONE,
LEFT(SUM(TOTNETTORIGA),LEN(SUM(TOTNETTORIGA))-2),
TABGRUPPI.DESCRIZIONE
FROM dbo.TESTEDOCUMENTI
INNER JOIN dbo.RIGHEDOCUMENTI ON PROGRESSIVO=IDTESTA
INNER JOIN dbo.ANAGRAFICAARTICOLI
ON CODART=ANAGRAFICAARTICOLI.CODICE
INNER JOIN dbo.TABCATEGORIE ON CATEGORIA=TABCATEGORIE.CODICE
INNER JOIN dbo.TABCATEGORIESTAT ON CODCATEGORIASTAT=TABCATEGORIESTAT.CODICE
INNER JOIN dbo.TABGRUPPI ON GRUPPO=TABGRUPPI.CODICE
LEFT JOIN dbo.ANAGRAFICAAGENTI ON ANAGRAFICAAGENTI.CODAGENTE=CODAGENTE1
WHERE ANAGRAFICAAGENTI.CODAGENTE = @AgentID AND dbo.TESTEDOCUMENTI.DOCCHIUSO = '0' AND dbo.TESTEDOCUMENTI.TIPODOC = 'FVC' AND dbo.TESTEDOCUMENTI.DATADOC BETWEEN DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())-2, 0) AND DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE())-2, -1)
GROUP BY GRUPPO,CATEGORIA,CODCATEGORIASTAT,TABCATEGORIE.DESCRIZIONE,TABCATEGORIESTAT.DESCRIZIONE,TABGRUPPI.DESCRIZIONE,ANAGRAFICAAGENTI.CODAGENTE,ANAGRAFICAAGENTI.DSCAGENTE
ORDER BY CODAGENTE DESC,SUM(TOTNETTORIGA) desc
--PRENDI IL PROSSIMO AGENTE---
FETCH NEXT FROM c INTO @AgentID
END
--PULISCI---
CLOSE c
DEALLOCATE c
这让我有不同的 table,我想 table 中的每个代理都有一个。但它们都是空的。如果我在 WHERE 条件下删除 ANAGRAFICAAGENTI.CODAGENTE = @AgentID,我会得到相同的 table 但每个结果都相同。他们都是平等的。
SQL 最适合基于集合的操作,但是针对您的情况使用循环的一种方法是使用 CURSOR
和 FETCH
。您需要研究这些并将其正确应用于您的数据,特别是因为您说 "obtain this result but in separate table"。我不知道您是想插入新的 table 还是 return 单独的 window 窗格中的结果。这将帮助您入门
--declare a cursor which will be the ID's of your agents. You can use what ever you want to limit your data off of
DECLARE c CURSOR FOR
SELECT DISTINCT
CODAGENTE
FROM ANAGRAFICAAGENTI
DECLARE @AgentID VARCHAR(4)
--get the first agent id and place it into a variable
OPEN c
FETCH NEXT FROM c INTO @AgentID
--for each agent id, select some data where the agent id equals the current agent id in the cursor
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT
--put your code here for selecting, inserting into a table, etc
WHERE ANAGRAFICAAGENTI.CODAGENTE = @AgentID --or what ever is appropiate
--get the next agent
FETCH NEXT FROM c INTO @AgentID
END
--clean up
CLOSE c
DEALLOCATE c
为了加分,我建议您开始在代码中使用 table 别名。它将使您和其他人在未来更加清晰易读。
https://technet.microsoft.com/en-us/library/ms187455(v=sql.105).aspx
SQL Table Aliases - Good or Bad?
样本集
点击HERE到运行下面的代码...
IF OBJECT_ID('tempdb..#agents') IS NOT NULL DROP TABLE #agents
IF OBJECT_ID('tempdb..#items') IS NOT NULL DROP TABLE #items
create table #agents (AgentID varchar(2), name varchar(50))
insert into #agents values
('A1','Julius Cesar'),
('B2','Albert Einstien')
create table #items (AgentID varchar(2), ItemID int, ItemName varchar(50))
insert into #items (AgentID, ItemID, ItemName) values
('A1',1,'Apple'),
('A1',2,'Pear'),
('A1',3,'Watermelon'),
('A1',4,'Grape'),
('B2',5,'Car'),
('B2',6,'Truck'),
('B2',7,'Van')
DECLARE c CURSOR FOR
SELECT DISTINCT
AgentID
FROM #agents
DECLARE @AgentID VARCHAR(4)
--get the first agent id and place it into a variable
OPEN c
FETCH NEXT FROM c INTO @AgentID
--for each agent id, select some data where the agent id equals the current agent id in the cursor
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT
AgentID, ItemID, ItemName
FROM #items
WHERE AgentID = @AgentID --or what ever is appropiate
--get the next agent
FETCH NEXT FROM c INTO @AgentID
END
--clean up
CLOSE c
DEALLOCATE c
如果我没有正确理解你的问题,那么我认为你可以使用 cross apply
运算符。
为了说明我的意思,让我们查找一些示例数据。一开始我声明了三个临时的tables用于代理,产品和交易这样
declare @Agents table (AgentId int, AgentName nvarchar(max));
declare @Products table (ProductId int, ProductName nvarchar(max), Price money);
declare @Transactions table (TransactionId int, TransactionDate date, AgentId int, ProductId int, Quantity int);
然后我用这样的示例数据填充 tables
insert into @Agents
values (1, N'Agnet1'), (2, N'Agent2'), (3, N'Agent3'), (4, N'Agent4');
insert into @Products
values (1, N'Product1', 100), (2, N'Product2', 150.50), (3, N'Product3', 200), (4, N'Product4', 50.23);
insert into @Transactions
values (1, '20160604', 1, 1, 5), (2, '20160704', 2, 1, 10), (3,'20160612', 2, 1, 15), (4, '20160604', 1, 2, 7),
(5, '20160720', 3, 4, 1), (6, '20160604', 2, 4, 3), (7, '20160730', 4, 3, 8), (8, '20160612', 2, 3, 13),
(9, '20160708', 4, 2, 6), (10, '20160705', 1, 3, 1), (11, '20160616', 4, 2, 17), (12, '20160709', 2, 3, 13);
使用该示例数据,我准备了此查询以获取每个代理的统计信息
declare @year int;
declare @month int;
select a.AgentName,
trans.ProductName,
trans.Amount
from @Agents as a
cross apply
( select t.ProductId,
max(p.ProductName) as ProductName,
sum(t.Quantity * p.Price) as Amount
from @Transactions as t
inner join @Products as p on p.ProductId = t.ProductId
where t.AgentId = a.AgentId
and year(t.TransactionDate) = @year
and month(t.TransactionDate) = @month
group by t.ProductId) as trans
对于输出上的 @year = 2016
和 @month = 6
你可以看到这个
AgentName ProductName Amount
Agnet1 Product1 500,00
Agnet1 Product2 1053,50
Agent2 Product1 1500,00
Agent2 Product3 2600,00
Agent2 Product4 150,69
Agent4 Product2 2558,50
对于 @year = 2016
和 @month = 7
你会看到这个
AgentName ProductName Amount
Agnet1 Product3 200,00
Agent2 Product1 1000,00
Agent2 Product3 2600,00
Agent3 Product4 50,23
Agent4 Product2 903,00
Agent4 Product3 1600,00
如您所见,我要求每个代理表单 @Agents
table 并且我对每个代理执行额外的查询,从 [=21= 中检索有关产品和总金额的数据] table.