为另一个表的每一行循环相同的查询

时间:2016-08-02 10:03:52

标签: sql-server tsql sql-server-2005

我试图获取不同表中每一行的循环结果。我需要知道哪个产品系列,每个销售代理商,在一个月内销售。

我的查询向我展示了如何知道产品系列的总数。我只需要插入其中," CODAGENT"在where where条件下,通过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----

我需要获得此结果,但需要在每个代理的单独表中

    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

这让我有不同的表,我认为,表中的每个代理都有一个。但他们都是空的。如果我在WHERE条件中删除ANAGRAFICAAGENTI.CODAGENTE = @AgentID,我获得相同的表,但每个表的结果相同。他们都是平等的。

2 个答案:

答案 0 :(得分:1)

SQL最适合基于集合的操作,但是为您的案例使用循环的一种方法是使用CURSORFETCH。您需要研究这些并将其正确应用于您的数据,特别是因为您说“获得此结果但在单独的表中”。我不知道您是否要插入新表或只是将结果返回到单独的窗格中。这将帮助您入门

--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

对于奖励积分,我建议你开始在代码中使用表别名。它将使你和其他人在将来更加清晰。

https://technet.microsoft.com/en-us/library/ms187455(v=sql.105).aspx

SQL Table Aliases - Good or Bad?

SAMPLE SET

点击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

答案 1 :(得分:0)

如果我正确地解决了您的问题,那么我认为您可以使用cross apply运算符。

要显示我的意思,请查看一些示例数据。在开始时,我为这样的代理商,产品和交易宣布了三个临时表

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); 

然后我用这样的样本数据填充表格

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表,并为每个表执行额外的查询,从@Transactions表中检索有关产品和总金额的数据。< / p>