2016-08-02 10 views
1

異なるテーブルの各行に対してループ結果を取得しようとしています。私はどの製品ライン、各販売代理店が1ヶ月で販売するのか知る必要があります。別のテーブルのすべての行に対して同じクエリをループする

私は、製品ラインの合計を知る方法を示す質問をしました。私はその中に挿入する必要があるのは、エージェントのテーブル内の各エージェントをループするwhere条件の "CODAGENT"だけです。だから、SQL言語ではない例を作る。私はそれはイタリア語だあなたは

にこの新しいステップに達しました
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 

を理解していれば、私は知らない

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 

エージェントごとにこの結果を得るために必要があるが、別のテーブルで

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

私の目標を達成するが、まだ動作しません。これは私のクエリです:

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

これは、テーブル内のエージェントごとに1つずつ異なるテーブルを作ってくれます。しかし、彼らはすべて空です。 WHERE条件でANAGRAFICAAGENTI.CODAGENTE = @AgentIDを削除すると、同じテーブルが得られますが、それぞれのテーブルで同じ結果が得られます。彼らはすべて平等です。

+0

これは何を意味するのですか?#CODAGENT = Row 1,2,3、.... – TheGameiswar

+0

あなたがやろうとしていることを使って説明してください。ループのある方法があるかもしれません。 – TheGameiswar

+0

SQLカーソルをチュートリアルhttp://www.kodyaz.com/articles/cursor.aspxに示されています。しかし、パフォーマンス上の理由からSQL Serverの問題を解決するための最後の方法はカーソルであることに注意してください。 – Eralper

答えて

1

SQLは、セットベースの操作で最も効果的ですが、ケースにループを使用する方法の1つは、FETCHCURSORを使用しています。 「この結果が得られるが、別のテーブルにある」と言っているので、これらを調べてデータに正しく適用する必要があります。私はあなたが新しいテーブルに挿入したいのか、別のウィンドウペインに結果を返すのか分かりません。これにより、あなたは始めるでしょう

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

サンプルセット以下のコードを実行するための

クリック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 
+0

最初は動作しません。それから、どこで終わりを取り除き、各エージェントについてテーブルを作成しますが、テーブルはすべて空です。 WHERE ANAGRAFICAAGENTI.CODAGENTE = @AgentID条件を削除して残りの部分をすべて残しておけば、同じ結果を持つすべてのテーブルがあります---このエラーが発生した場合は、メッセージ156、レベル15、状態1、行39 キーワード 'CLOSE'の近くに構文が正しくありません。また、唯一の 'SELECT codagente1、 datadoc、tipodocとスクリプトのサンプルバージョンと – BigBlack

+0

しようと試み、INOXDGI.dbo.TESTEDOCUMENTI FROM codclifor LEFT JOIN dbo.ANAGRAFICAAGENTI ON CODAGENTE = CODAGENTE1 WHERE TESTEDOCUMENTI.CODAGENTE1 = @ AgentID' – BigBlack

+0

@BigBlack私は誤ってそこに追加の 'END'を残しました。それを私が直した。それは実行され、私はサンプルを提供した。 – scsimon

0

私が正しくあなたの問題をunserstandなら、私はあなたのことを考えます演算子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); 

そして、私が用意してきたそのサンプルデータを持つようないくつかのサンプルデータを含むテーブルという埋める、薬のための3つの一時テーブルを宣言しますあなたがこれを見ることができる出力に@year = 2016@month = 6については、各エージェント

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 

の統計情報を取得するには、このクエリ

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テーブルのために求めていると、それらのそれぞれのために私はretrive追加のクエリを実行見ることができるようにそれ自体意志のために製品に関するデータと合計量は@Transactionsテーブルからです。

+0

zajoncありがとうございますが、これはほとんどの代理店を1ヶ月持つことですが、私はそれが好きですが、私が今必要なのは、以下のscsimonの解決策です。どこにでもありがとう! – BigBlack

関連する問題