2016-08-31 16 views
0

マイアプリケーションは現金登録です。次のクエリは、トランザクションIDを受け取り、= 28715 TRANSACTIONIDのために、すなわち、この単一のトランザクションで販売された商品の1つまたは複数の行を返します。内部変数を持つSQLサブクエリを返します。

DECLARE @SalesItems varchar(250); 
DECLARE @TransactionID int; 
SET @TransactionID = 28715; 


Select @SalesItems = coalesce(@SalesItems + ', ', '') + CAST(TransactionsPosLines.Description as varchar(250)) 
From 
    TransactionsPosLines 
    where TransactionsPosLines.TransactionId = @TransactionID 

select @SalesItems 

とリターン:

"Widget A, Widget B, Widget C" as a single string. 

私もその日のトランザクションの終了を持っています私は文字列(ウィジェットAなど...)をトランザクションレポートの最後に追加するレポートを作成します。私はこのレポートを実行すると

 Select 
      Transactions.TransactionId, 
      Transactions.TransactionDate, 
      Transactions.MoneyIn, 
      Transactions.MoneyOut, 
      Transactions.Description, 
      PaymentMethods.PaymentMethodName, 
      Transactions.TransactionRef, 
      Membership.Username, 
      Tills.Description As 'Till Name', 
      Transactions.Reason, 
    -- FOR THIS LAST COLUMN HERE I WANT TO SHOW THE OUTPUT OF THE QUERY ABOVE 
====>  SalesItems 
     From 
      Transactions Left Outer Join 
      Tills 
      On Transactions.TillId = Tills.TillId Inner Join 
      PaymentMethods 
      On Transactions.PaymentMethodId = PaymentMethods.PaymentMethodsID Inner Join 
      Membership 
      On Transactions.UserId = Membership.UserId Inner Join 
     Where 
      Transactions.TransactionDate >= @DateStart And 
      Transactions.TransactionDate <= @DateEnd 

は、だから私はこのような何かを得る:

TransactionId TransactionDate MoneyIn MoneyOut Description PaymentMethodName TransactionRef Username Till Name Reason SalesItems 
28715 31/08/2016 09:07 119.99 0 Sale - Card Card 24881 Chantal Till1 Null Widget A, Widget B, Widget C 
+0

Huh ????これはまったく意味がありません。変数はスカラーであり、複数の値を保持することはできません。また、クエリの途中でそのような値を変数に代入することはできません。掲載されているとおり、これはあなたが何をしようとしているのかはまったく明らかではありません。 –

+0

@SeanLange変数の割り当てが機能するかどうか:http://dba.stackexchange.com/questions/68089/how-to-use-coalesce-with-multiple-rows-and-without-preceding-comma – Matt

+0

@Matt look close、 select文の1つの列が変数を割り当てており、他の列が結果セットの値を戻しています。それは動作しません。もちろん、selectステートメントを使って変数に値を代入できますが、ここに掲示されているコンテキストには値を代入することはできません。 –

答えて

1

CROSS APPLY WITH FOR XML CONCATENATION METHOD:

Select 
    t.TransactionId, 
    t.TransactionDate, 
    t.MoneyIn, 
    t.MoneyOut, 
    t.Description, 
    p.PaymentMethodName, 
    t.TransactionRef, 
    m.Username, 
    tl.Description As 'Till Name', 
    t.Reason, 
    c.SalesItems 
From 
    Transactions t 
    LEFT JOIN Tills tl 
    ON t.TillId = tl.TillId 
    INNER JOIN PaymentMethods p 
    ON t.PaymentMethodId = p.PaymentMethodID 
    INNER JOIN Membership m 
    On t.UserId = m.UserId 
    CROSS APPLY 
    (SELECT STUFF(
     (SELECT ',' + CAST(tp.Description AS VARCHAR(100)) 
     FROM 
      TransactionPostLines tp 
     WHERE t.TransactionId = tp.TransactionId 
     FOR XML PATH('')) 
     ,1,1,'') as SalesItems) c 
Where 
    t.TransactionDate >= @DateStart 
    AND t.TransactionDate <= @DateEnd 

ASサブ列の定義で選択します。

Select 
    t.TransactionId, 
    t.TransactionDate, 
    t.MoneyIn, 
    t.MoneyOut, 
    t.Description, 
    p.PaymentMethodName, 
    t.TransactionRef, 
    m.Username, 
    tl.Description As 'Till Name', 
    t.Reason, 
    STUFF(
     (SELECT ',' + CAST(tp.Description AS VARCHAR(100)) 
     FROM 
      TransactionPostLines tp 
     WHERE t.TransactionId = tp.TransactionId 
     FOR XML PATH('')) 
     ,1,1,'') as SalesItems 
From 
    Transactions t 
    LEFT JOIN Tills tl 
    ON t.TillId = tl.TillId 
    INNER JOIN PaymentMethods p 
    ON t.PaymentMethodId = p.PaymentMethodID 
    INNER JOIN Membership m 
    On t.UserId = m.UserId 
Where 
    t.TransactionDate >= @DateStart 
    AND t.TransactionDate <= @DateEnd 

注使用して、表の別名は、コードやすくなりますが読んで書くこと!

+0

完璧、ありがとうございます。まさに私が何をしたのか。どの方法がこれを行うには最良の(正しい)方法でしょうか? – Belliez

+0

これはもっと個人的な好みです。あなたの意図がもっと分かって、fromセクションの関係を示しているので、CROSS APPLYを使用すると言う人もいますが、実際に実行計画を見ることはできませんが、同じであると仮定します。 – Matt

1

私はあなたのメイン・クエリの各行に内側のクエリに結果を適用するために適用され、クロスを使用していました。これはあなたを助けかどうかを確認します。

Select 
     Transactions.TransactionId, 
     Transactions.TransactionDate, 
     Transactions.MoneyIn, 
     Transactions.MoneyOut, 
     Transactions.Description, 
     PaymentMethods.PaymentMethodName, 
     Transactions.TransactionRef, 
     Membership.Username, 
     Tills.Description As 'Till Name', 
     Transactions.Reason, 
-- HERE >> 
     --SalesItems = 
     dt.salesItems 
    From 
     Transactions Left Outer Join 
     Tills 
     On Transactions.TillId = Tills.TillId Inner Join 
     PaymentMethods 
     On Transactions.PaymentMethodId = PaymentMethods.PaymentMethodsID Inner Join 
     Membership 
     On Transactions.UserId = Membership.UserId 
     cross apply (
    select distinct stuff((
    Select ',' + CAST(TransactionsPosLines.Description as varchar(250)) 
From 
    TransactionsPosLines 
    where TransactionsPosLines.TransactionId = Transactions.TransactionId 
    FOR XML PATH('')),1,1,'') as salesItems 
) as dt 
    -- TransactionsPosLines 
    -- On TransactionsPosLines.TransactionId = Transactions.TransactionId 
    Where 
     Transactions.TransactionDate >= @DateStart And 
     Transactions.TransactionDate <= @DateEnd 
関連する問題