繁体   English   中英

将表中的数据合并到一行T-SQL

[英]Combine data from a table to one row T-SQL

我在#SQL server 2008中有一个包含事务数据的表。 该表看起来像这样。 我想在sql语句中有这个。

TRANSACTIONID | TransactionDate | TRANSACTIONTYPE |金额|资产|用户ID

交易类型可以是四种类型之一:存款,取款,利润和股权。 我举一个例子说明它在事务表中的样子。 余额是金额总和列。

TransactionId|TransactionDate|TransactionType|Amount|Balance|UserId
1|             2013-03-25|      Deposit|         150|    150|     1
2|             2013-03-27|      Stake|           -20|    130|     1
3|             2013-03-28|      Profit |         1500|   1630|    1
4 |            2013-03-29|      Withdrawals|     -700|   930|     1
5|             2013-03-29|      Stake |          -230 |  700 |    1
6|             2013-04-04|      Stake|           -150 |  550|     1
7|             2013-04-06|      Stake |          -150 |  400|     1

我现在想要的是获得一个select语句,它为我提供按周分组的所有数据。 结果应该是这样的。

Week|Deposit|Withdrawals|Stake|Profit|Balance|Year
13 |  150|     -700  |      -250 | 1500 |  700 |    2013
14 |  0  |     0     |      -300|  0   |   400 |    2013

我也有几周的问题......我住在欧洲一个星期的第一天是星期一。 我有一个解决方案,但在一年结束时,我有时会得到54周,但一年只有52周......

我希望有人可以帮助我。

这就是我到目前为止所拥有的。

SELECT transactionid, 
       transactiondate, 
       transactiontype, 
       amount, 
       (SELECT Sum(amount) 
        FROM   transactions AS trans_ 
        WHERE  trans_.transactiondate <= trans.transactiondate 
               AND userid = 1)         AS Balance, 
       userid, 
       Datepart(week, transactiondate) AS Week, 
       Datepart(year, transactiondate) AS Year 
FROM   transactions trans 
WHERE  userid = 1 
ORDER  BY transactiondate DESC, 
          transactionid DESC 

这里的示例数据和我对sql-fiddle的查询: http ://www.sqlfiddle.com/#!3/79d65 / 92/0

为了将行中的数据转换为列,您将需要使用PIVOT函数。

您没有指定要返回的balance值,但根据最终结果,您希望最终余额为与每天的最后交易日期相关联的值。 如果这不正确,那么请说明逻辑应该是什么。

为了获得结果,您将需要使用DATEPARTYEAR函数。 这些将允许按周和年值进行分组。

以下查询应该获得您想要的结果:

select week, 
  coalesce(Deposit, 0) Deposit, 
  coalesce(Withdrawals, 0) Withdrawals, 
  coalesce(Stake, 0) Stake, 
  coalesce(Profit, 0) Profit,
  Balance,
  Year
from
(
  select datepart(week, t1.transactiondate) week,
    t1.transactiontype,
    t2.balance,
    t1.amount,
    year(t1.transactiondate) year
  from transactions t1
  cross apply
  (
    select top 1 balance 
    from transactions t2
    where datepart(week, t1.transactiondate) = datepart(week,  t2.transactiondate)
      and year(t1.transactiondate) = year(t2.transactiondate)
      and t1.userid = t2.userid
    order by TransactionId desc
  ) t2
) d
pivot
(
  sum(amount)
  for transactiontype in (Deposit, Withdrawals, Stake, Profit)
) piv;

请参阅SQL Fiddle with Demo 结果是:

| WEEK | DEPOSIT | WITHDRAWALS | STAKE | PROFIT | BALANCE | YEAR |
------------------------------------------------------------------
|   13 |     150 |        -700 |  -250 |   1500 |     700 | 2013 |
|   14 |       0 |           0 |  -300 |      0 |     400 | 2013 |

作为附注,你说你的星期一是星期一,你可能必须使用DATEFIRST函数来设置一周的第一天。

另一种选择,不使用PIVOT,而是使用少量CASE

WITH CTE AS
(
    SELECT
         TransactionId 
        ,TransactionDate
        ,DATEPART(WEEK, TransactionDate) AS Week
        ,CASE WHEN TransactionType='Deposit' THEN Amount ELSE 0 END AS Deposit 
        ,CASE WHEN TransactionType='Stake' THEN Amount ELSE 0 END AS Stake 
        ,CASE WHEN TransactionType='Profit' THEN Amount ELSE 0 END AS Profit 
        ,CASE WHEN TransactionType='Withdrawals' THEN Amount ELSE 0 END AS Withdrawals 
        ,Balance
        ,DATEPART(YEAR, TransactionDate) AS Year
    FROM dbo.Transactions
)
SELECT 
  Week,  SUM(Deposit) AS Deposit, SUM(Withdrawals) AS Withdrawals, SUM(Stake) AS Stake, SUM(Profit) AS Profit, 
    (SELECT Balance FROM CTE i WHERE i.TransactionID = MAX(o.TransactionID)) AS BAlance, Year
FROM CTE o
GROUP BY Week, Year

SQLFiddle演示

http://www.sqlfiddle.com/#!3/79d65/89

;WITH cte AS
(
  SELECT datepart(ww, transactiondate) wk,
  sum(CASE WHEN TransactionType = 'Deposit' THEN Amount ELSE 0 END) AS D,
  sum(CASE WHEN TransactionType = 'Withdrawals' THEN Amount ELSE 0 END)  AS W,
  sum(CASE WHEN TransactionType = 'Profit' THEN Amount ELSE 0 END) AS P,
  sum(CASE WHEN TransactionType = 'Stake' THEN Amount ELSE 0 END)  AS S,
  sum(
    CASE WHEN TransactionType = 'Deposit' THEN Amount ELSE 0 END +
    CASE WHEN TransactionType = 'Withdrawals' THEN Amount ELSE 0 END +
    CASE WHEN TransactionType = 'Profit' THEN Amount ELSE 0 END +
    CASE WHEN TransactionType = 'Stake' THEN Amount ELSE 0 END +
    CASE WHEN TransactionType = 'Balance' THEN Amount ELSE 0 END) AS wkTotal
  FROM transactions
  GROUP BY datepart(ww, transactiondate)),
  cte1 AS
  (
    SELECT *, row_number() over (ORDER BY wk) AS rowNum
    FROM cte)
  SELECT wk, d, w, p, s, wktotal
  + coalesce((SELECT top 1 wktotal FROM cte1 x WHERE x.rownum < m.rownum ), 0) AS RunningBalance
FROM cte1 m

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM