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

标签 sql sql-server-2008 tsql pivot

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

TransactionId|TransactionDate|TransactionType|Amount|Balance|UserId

交易类型可以是存款、取款、利润和股权四种类型之一。我举例说明它在交易表中的样子。余额为 Sum of amount 列。

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函数设置一周的第一天。

关于sql - 将表中的数据合并到一行 T-SQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15719445/

相关文章:

php - 想要按类型转换排序但按值(value)排序

sql-server - 将动态sql的结果转换为xml

c# - SQL Server 2008 R2 查询通知上的死锁 (SqlDependency)

visual-studio-2010 - 比较 SQL Server 数据库架构

sql - INSERT INTO SELECT - 大量记录

sql - 您可以打印 SQL Server View 的图形表示吗?

sql - 同一 View 上具有不同条件的两个计数查询

tsql - SQL 表分页性能 ...EF4 + Linq SKIP +TAKE 与使用 TSQL 参数在 SQL 表上请求 "paging"的性能相同吗?

tsql - 当 NULL anchor 在 NOT NULL 字段上重复出现时,如何解决 CTE 中的类型不匹配问题

sql - Oracle Exadata - LEFT OUTER JOIN 在连接条件下使用 AND 时表现得像 INNER