不使用游标编写查询

时间:2014-02-07 22:13:36

标签: sql cursor

我写了这个查询来显示单个客户的账户交易:

select *
from (
    select top 1 
       [id]
      ,[client_id]
      ,[transactionDate]
      ,N'revolving balance' [details]
      ,NULL [amount]
      ,NULL [debit]
      ,NULL [credit]
      ,[balance]
  FROM [dbo].[bsitems]
  where [client_id]=@client_id and
        [transactionDate] < @transactionDateFrom
        order by id desc) t1
        union
SELECT [id]
      ,[client_id]
      ,[transactionDate]
      ,[details]
      ,[amount]
      ,[debit]
      ,[credit]
      ,[balance]
  FROM [dbo].[bsitems]
  where [client_id]=@client_id and
        [transactionDate] between @transactionDateFrom and @transactionDateTo

如何显示“客户”表中存在的所有客户端的事务?假设客户端表结构是(id,name)

2 个答案:

答案 0 :(得分:0)

SELECT *
FROM (
    SELECT TOP 1 
         [id]
        ,[client_id]
        ,[transactionDate]
        ,N'revolving balance' [details]
        ,NULL [amount]
        ,NULL [debit]
        ,NULL [credit]
        ,[balance]
    FROM [dbo].[bsitems]
    INNER JOIN [dbo].[client] ON [dbo].[bsitems].[client_id] = [dbo].[client].[id]
    AND [transactionDate] < @transactionDateFrom
    ORDER BY id DESC
) t1

UNION

SELECT 
     [id]
    ,[client_id]
    ,[transactionDate]
    ,[details]
    ,[amount]
    ,[debit]
    ,[credit]
    ,[balance]
FROM [dbo].[bsitems]
INNER JOIN [dbo].[client] ON [dbo].[bsitems].[client_id] = [dbo].[client].[id]
AND [transactionDate] between @transactionDateFrom and @transactionDateTo

答案 1 :(得分:0)

对于第二部分(实际上是交易),只需使用join

SELECT b.id, b.client_id, b.transactionDate, b.details,
       b.amount, b.debit, b.credit, b.balance
FROM [dbo].[bsitems] b join
     clients c
     on b.client_id = c.client_id
WHERE transactionDate between @transactionDateFrom and @transactionDateTo;

这假设client_id存储在clients表中。

查询的第一部分是在起始日期之前返回最新的id。如果没有先前的事务,则不返回任何行。你可以用类似的方式解决这个问题。

select id, client_id, transactiondate, details, amount, debit, credit, balance
from (SELECT b.id, b.client_id, b.transactionDate,
             N'revolving balance' as b.details,
             NULL as b.amount, NULL as b.debit, NULL as b.credit,
             b.balance,
             row_number() over (partition by client_id order by TransactionDate desc) as seqnum
      FROM [dbo].[bsitems] b join
           clients c
           on b.client_id = c.client_id
      WHERE transactionDate < @transactionDateFrom
     ) t
where seqnum = 1;

而不是top 1这是使用row_number()在截止日期之前为事务分配顺序值。然后选择最新的这些。

最终结果只是这两个查询的union all

select id, client_id, transactiondate, details, amount, debit, credit, balance
from (SELECT b.id, b.client_id, b.transactionDate,
             N'revolving balance' as b.details,
             NULL as b.amount, NULL as b.debit, NULL as b.credit,
             b.balance,
             row_number() over (partition by client_id order by TransactionDate desc) as seqnum
      FROM [dbo].[bsitems] b join
           clients c
           on b.client_id = c.client_id
      WHERE transactionDate < @transactionDateFrom
     ) t
where seqnum = 1
union all
SELECT b.id, b.client_id, b.transactionDate, b.details,
       b.amount, b.debit, b.credit, b.balance
FROM [dbo].[bsitems] b join
     clients c
     on b.client_id = c.client_id
WHERE transactionDate between @transactionDateFrom and @transactionDateTo;