返回带有变量的SQL子查询选择

时间:2016-08-31 14:57:08

标签: sql sql-server

我的申请是收银机。以下查询采用TransactionID并返回此单个事务中出售的一行或多行项目,即TransactionID = 28715:

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.

我还有一个结束日交易报告,我想将字符串(Widget 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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

用于XML连接方法的交叉应用:

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 Sub Select选择列定义:

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

注意使用表别名可以使代码更易于阅读和编写!