zoukankan      html  css  js  c++  java
  • SQL代码之多组织数据汇总成树形表格展示

    需求多组织(一个数据库实例里面,存在一个总公司数据库,多个分公司数据库)环境中,以总公司的会计科目为主(分公司可能不存在总公司存在的科目),以树形结构的方式展示各个科目下每个公司的该科目对应的余额数据。每类科目有一个余额汇总小计,最后再做一个全部余额合计,本例中使用一个总公司,一个分公司做的演示

    效果如下所示

     准备工作:

    1、在数据库中创建两个数据库,一个 MyWorkTest (表示总公司) 一个 MyWorkTestBackUp(表示分公司)

    2、分别在两个数据库中执行表结构sql语句(没用注释的部分两个表都需要执行,注释的部分,只需要执行对应数据库的sql部分)

    3、准备treetable插件

    4、本例用的是MVC 需要将MVC的模板 _ViewStart 中的Layout设置为null

    代码实现:

    1、表结构SQL

    --公司信息
    Create Table MyWorkTest_CompanyInfo(
        id int IDENTITY(1,1) NOT NULL,
        fullname nvarchar(10) NOT NULL,
        isHeader bit not null,
        dbname nvarchar(100) not null
    )
    GO
    delete from MyWorkTest_CompanyInfo
    insert into MyWorkTest_CompanyInfo(fullname,isHeader,dbname)
    select '总公司',1,'MyWorkTest' UNION ALL
    select '成都分公司',0,'MyWorkTestBackUp'
    GO
    
    --科目信息
    Create Table MyWorkTest_Atype(
        typeid nvarchar(50) not null,
        parid nvarchar(50) not null,
        leveal smallint not null,
        sonnum int not null,
        fullname nvarchar(66) not null,
        usercode nvarchar(50) not null,
        balance numeric(18,2) default(0)
    )
    GO
    
    delete from MyWorkTest_Atype
    /*
    --MyWorkTest 数据库数据
    --资产类
    insert into MyWorkTest_Atype(typeid,parid,leveal,sonnum,fullname,usercode,balance)
    select '00000','root','0','5','全部科目','00',0 UNION ALL
    select '00001','00000','1','3','资产类','10',0 UNION ALL  --17640
    select '0000100001','00001','2','0','库存现金','1001',10000 UNION ALL
    select '0000100002','00001','2','2','银行存款','1002',0 UNION ALL --7520
    select '000010000200001','0000100002','3','0','建设银行','100201',1020 UNION ALL
    select '000010000200002','0000100002','3','2','工商银行','100202',0 UNION ALL --6500
    select '00001000020000200001','000010000200002','4','0','成都工商银行','10020201',4000 UNION ALL
    select '00001000020000200002','000010000200002','4','0','绵阳工商银行','10020202',2500 UNION ALL
    select '0000100003','00001','2','2','其他货币资金','1003',0 UNION ALL  --120
    select '000010000300001','0000100003','3','0','外埠存款','100301',20 UNION ALL
    select '000010000300002','0000100003','3','0','信用卡','100302',100 
    
    --负债类
    insert into MyWorkTest_Atype(typeid,parid,leveal,sonnum,fullname,usercode,balance)
    select '00002','00000','1','4','负债类','20',0 UNION ALL  --1073
    select '0000200001','00002','2','0','短期借款','2001',10 UNION ALL
    select '0000200002','00002','2','2','应付账款','2002',0 UNION ALL --33
    select '000020000200001','0000200002','3','0','应付货款','200201',11 UNION ALL
    select '000020000200002','0000200002','3','0','应付加工费','200202',22 UNION ALL
    select '0000200003','00002','2','1','应交税费','2003',0 UNION ALL --30
    select '000020000300001','0000200003','3','2','应交增值税','200301',0 UNION ALL --30
    select '00002000030000100001','000020000300001','4','0','进项税额','20030101',10 UNION ALL
    select '00002000030000100002','000020000300001','4','0','己交税金','20030102',20 UNION ALL
    select '0000200004','00002','2','','应付职工薪酬','2004',1000
    
    --共同类
    insert into MyWorkTest_Atype(typeid,parid,leveal,sonnum,fullname,usercode,balance)
    select '00003','00000','1','1','共同类','30',0 UNION ALL  --30
    select '0000300001','00003','2','0','货币兑换','3001',10 UNION ALL
    select '0000300002','00003','2','0','总公司有子公司没有的项目','3002',20 
    
    
    --所有者权益
    insert into MyWorkTest_Atype(typeid,parid,leveal,sonnum,fullname,usercode,balance)
    select '00004','00000','1','2','所有者权益','40',0 UNION ALL  --350
    select '0000400001','00004','2','0','实收资本','4001',150 UNION ALL
    select '0000400002','00004','2','0','盈余公积','4002',200 
    
    
    --成本类
    insert into MyWorkTest_Atype(typeid,parid,leveal,sonnum,fullname,usercode,balance)
    select '00005','00000','1','1','成本类','50',0  UNION ALL  --30
    select '0000500001','00005','2','2','生产成本','5001',0 UNION ALL  --30
    select '000050000100001','0000500001','3','0','基本生产成本','500101',10 UNION ALL
    select '000050000100002','0000500001','3','0','辅助生产成本','500102',20
    */
    
    /*
    --MyWorkTestBackUp 数据库数据
    insert into MyWorkTest_Atype(typeid,parid,leveal,sonnum,fullname,usercode,balance)
    select '00000','root','0','5','全部科目','00',0 UNION ALL
    select '00001','00000','1','3','资产类','10',176.2 UNION ALL
    select '0000100001','00001','2','0','库存现金','1001',100 UNION ALL
    select '0000100002','00001','2','2','银行存款','1002',75 UNION ALL
    select '000010000200001','0000100002','3','0','建设银行','100201',10 UNION ALL
    select '000010000200002','0000100002','3','2','工商银行','100202',65 UNION ALL
    select '00001000020000200001','000010000200002','4','0','成都工商银行','10020201',40 UNION ALL
    select '00001000020000200002','000010000200002','4','0','绵阳工商银行','10020202',25 UNION ALL
    select '0000100003','00001','2','2','其他货币资金','1003',1.20 UNION ALL
    select '000010000300001','0000100003','3','0','外埠存款','100301',0.20 UNION ALL
    select '000010000300002','0000100003','3','0','信用卡','100302',1 
    --负债类
    insert into MyWorkTest_Atype(typeid,parid,leveal,sonnum,fullname,usercode,balance)
    select '00002','00000','1','4','负债类','20',1.73 UNION ALL
    select '0000200001','00002','2','0','短期借款','2001',0.1 UNION ALL
    select '0000200002','00002','2','2','应付账款','2002',0.33 UNION ALL
    select '000020000200001','0000200002','3','0','应付货款','200201',0.11 UNION ALL
    select '000020000200002','0000200002','3','0','应付加工费','200202',0.22 UNION ALL
    select '0000200003','00002','2','1','应交税费','2003',0.3 UNION ALL
    select '000020000300001','0000200003','3','2','应交增值税','200301',0.3 UNION ALL
    select '00002000030000100001','000020000300001','4','0','进项税额','20030101',0.1 UNION ALL
    select '00002000030000100002','000020000300001','4','0','己交税金','20030102',0.2 UNION ALL
    select '0000200004','00002','2','','应付职工薪酬','2004',1
    --共同类
    insert into MyWorkTest_Atype(typeid,parid,leveal,sonnum,fullname,usercode,balance)
    select '00003','00000','1','1','共同类','30',0.1 UNION ALL
    select '0000300001','00003','2','0','货币兑换','3001',0.1 
    --所有者权益
    insert into MyWorkTest_Atype(typeid,parid,leveal,sonnum,fullname,usercode,balance)
    select '00004','00000','1','2','所有者权益','40',0.35 UNION ALL
    select '0000400001','00004','2','0','实收资本','4001',0.15 UNION ALL
    select '0000400002','00004','2','0','盈余公积','4002',0.2 
    --成本类
    insert into MyWorkTest_Atype(typeid,parid,leveal,sonnum,fullname,usercode,balance)
    select '00005','00000','1','1','成本类','50',0.3 UNION ALL
    select '0000500001','00005','2','2','生产成本','5001',0.3 UNION ALL
    select '000050000100001','0000500001','3','0','基本生产成本','500101',0.1 UNION ALL
    select '000050000100002','0000500001','3','0','辅助生产成本','500102',0.2
    */
    View Code

    2、存储过程

    IF EXISTS ( SELECT  *
                FROM    dbo.sysobjects
                WHERE   id = OBJECT_ID(N'[dbo].[P_Inf_GetAtypeAssistantBalance]')
                        AND OBJECTPROPERTY(id, N'IsProcedure') = 1 )
      DROP PROCEDURE [dbo].[P_Inf_GetAtypeAssistantBalance]
    GO
    
    /*
        需求:多组织环境,以总公司的科目为参考(存在总公司有的科目在子公司没有的情况),统计每个公司的每个科目的余额情况
        以树形的方式显示科目,在末级显示各个公司该科目的余额情况,
        每个末级科目显示各个公司该科目余额的汇总数据,
        不同科目类一个科目余额小计,最后汇总一个全部余额合计
    */
    CREATE PROCEDURE P_Inf_GetAtypeAssistantBalance
    AS
    BEGIN
        SET NOCOUNT ON
        --变量申明
        DECLARE @ComName nvarchar(200),@DbName nvarchar(200), @IsHead bit, @Sql nvarchar(max)
        DECLARE @MaxLevel INT,@CIndex int
        DECLARE @CIndexStr nvarchar(200)
    
        -- 获取末级科目
        SELECT typeid,leveal
        INTO #AtypeCw 
        FROM MyWorkTest_Atype 
        WHERE sonnum = 0 
    
        --末级数据表
        CREATE TABLE #FinalData(
            CompanyID nvarchar(50),
            TypeID nvarchar(200),
            ParId nvarchar(200),
            BalanceTotal numeric(18,4),
            leveal int DEFAULT 0,
            CIndex nvarchar(200)
        )
        -- 获取末级数据封装
        set @CIndex =1
        Declare my_cursor Cursor For Select dbname, fullname,isHeader  From MyWorkTest_CompanyInfo Where dbname <> ''  Order By isHeader Desc
        Open my_cursor
        Fetch Next From my_cursor Into @DbName, @ComName,@IsHead
        While @@Fetch_Status = 0
        BEGIN
            SET @CIndexStr = right(cast(right('0000'+rtrim(@CIndex),4) as varchar(4)),4)
            SET @SQL ='select '''+@ComName+''', a.typeid,a.parid,a.balance,a.leveal,'''+@CIndexStr+''' AS cindex  from ['+@DbName+']..MyWorkTest_Atype  a
            INNER join #AtypeCw b on a.typeid = b.typeid'
            INSERT INTO #FinalData(CompanyID,TypeID,ParId,BalanceTotal,leveal,CIndex)
            exec (@Sql) 
    
            INSERT INTO #FinalData(CompanyID,TypeID,ParId,BalanceTotal,leveal,CIndex)    
            SELECT @ComName AS CompanyID,A.typeid,left(A.typeid,LEN(A.typeid)- 5) AS ParId,0 as BalanceTotal,0 AS leveal,@CIndexStr AS CIndex
            FROM #AtypeCw A LEFT JOIN #FinalData B ON A.typeid = B.TypeID AND b.CompanyID = @ComName
            WHERE B.TypeID IS NULL 
            GROUP BY A.typeid
            SET @CIndex = @CIndex+1
        Fetch Next From my_cursor Into @DbName, @ComName,@IsHead
        End
        Close my_cursor
        Deallocate my_cursor
     
        --在末级增加公司数据
        select LEFT(typeid,5) as ATypeIndex, tag, usercode, fullname,typeid,parId,balancetotal ,leveal,
        ROW_NUMBER() OVER(PARTITION By LEFT(typeid,5) Order By typeid,parId,tag ) as AtypeInnerIndex
        into #LastLevealData
        from (
            select 10 tag,a.usercode, a.fullname, f.TypeID,f.ParId, sum(BalanceTotal)AS BalanceTotal,a.leveal from #FinalData  f
            left join MyWorkTest_Atype  a on f.TypeID = a.typeid
            GROUP BY f.TypeID,a.fullname,f.ParId,a.leveal,a.usercode
            UNION ALL
            select 20 tag,'' AS usercode,CompanyID,TypeID+CIndex,TypeID, SUM(BalanceTotal) AS BalanceTotal,fc.leveal from #FinalData fc
            group by CompanyID,TypeID,ParId,fc.leveal,fc.CIndex
        ) t order by TypeID,tag
       
     
       --增加父级数据            
        SELECT @MaxLevel = max(leveal) FROM #LastLevealData            
        WHILE @MaxLevel > 1
          BEGIN
            INSERT INTO #LastLevealData(ATypeIndex,tag, usercode,fullname,typeid,parId,balancetotal,leveal,AtypeInnerIndex)
            SELECT LEFT(b.typeId,5) AS ATypeIndex ,10,b.usercode,b.FullName,b.typeId,b.parid,BalanceTotal,b.leveal,'' AS AtypeInnerIndex
            FROM 
            (
              SELECT DISTINCT LEFT(typeid, LEN(typeid)-5) as typeid,
                SUM(BalanceTotal) AS BalanceTotal
              FROM #LastLevealData  
              WHERE tag = 10 AND leveal = @MaxLevel
              GROUP BY LEFT(typeid, LEN(typeid)-5)            
            ) a
            INNER JOIN MyWorkTest_Atype b ON a.typeid = b.typeid 
            SET @MaxLevel = @MaxLevel - 1
         END 
    
        update #LastLevealData set parid = '00000' where leveal = 2 and tag = 10  
        update #LastLevealData set leveal = 9 where leveal = 1 and tag = 10
            
        -- 获取数据源
        select ATypeIndex,tag,usercode, fullname,typeid,parId,balancetotal,leveal,
        ROW_NUMBER() OVER(PARTITION By LEFT(typeid,5) Order By ATypeIndex ,typeid,tag) as AtypeInnerIndex
        into #DataSource
        from #LastLevealData 
        
        --小类合计放在每一类的最后面处理开始
        select ATypeIndex,tag,usercode, fullname,typeid,parId,balancetotal,leveal,
        ROW_NUMBER() OVER(Order By ATypeIndex,leveal,AtypeInnerIndex) as AtypeInnerIndex
        into #DataSourceRst
        from #DataSource
        
        delete from #DataSource 
        insert into #DataSource
        select * from #DataSourceRst
        --小类合计放在每一类的最后面处理结束
        
        --所有合计
        insert into #DataSource(ATypeIndex,tag,usercode, fullname,typeid,parId,balancetotal,leveal,AtypeInnerIndex) 
        select '99999' AS ATypeIndex,40 AS tag, '合计' AS usercode, '合计' AS fullname,'99999' AS typeid, '00000' AS  parId,sum(balancetotal), 0 as leveal,
        0 AS  AtypeInnerIndex 
        from #DataSource where leveal = 9 
        update #DataSource set usercode = fullname+'小计' where leveal = 9
        
        select * from #DataSource order by ATypeIndex
        
      --删除临时表
        DROP TABLE #AtypeCw
        DROP TABLE #FinalData
        DROP TABLE #LastLevealData
        DROP TABLE #DataSource
        DROP TABLE #DataSourceRst
        
    END
    GO
    View Code

    3、页面代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>tree-table</title>
        <link rel="stylesheet" href="/Content/TreeTable/assets/layui/css/layui.css">
        <link rel="stylesheet" href="/Content/TreeTable/assets/common.css" />
    </head>
    <body>
        <link rel="stylesheet" href="/Content/TreeTable/assets/layui/css/layui.css">
        <link rel="stylesheet" href="/Content/TreeTable/assets/common.css" />
        <p></p>
        <div class="layui-container">
            <div class="layui-btn-group">
                <button class="layui-btn" id="btn-expand">全部展开</button>
                <button class="layui-btn" id="btn-fold">全部折叠</button>
            </div>
            <table id="auth-table" class="layui-table" lay-filter="auth-table"></table>
        </div>
        <script src="~/Scripts/jquery-1.10.2.min.js"></script>
        <script src="/Content/TreeTable/assets/layui/layui.js"></script>
        <script>
        $.ajax({
            url: '/MyTest/GetDataSource',
            type: 'post',
            dataType: 'json',
            success: function (res) {
                layui.config({
                    base: '/Content/TreeTable/module/'
                }).extend({
                    treetable: 'treetable-lay/treetable'
                }).use(['table', 'treetable'], function () {
                    var $ = layui.jquery;
                    var table = layui.table;
                    var treetable = layui.treetable;
                    // 渲染表格
                    layer.load(2);
                    treetable.render({
                        data: res.data,
                        treeColIndex: 1,
                        treeSpid: '00000',
                        treeIdName: 'TypeId',
                        treePidName: 'ParId',
                        elem: '#auth-table',
                        page: false,
                        cols: [[
                            { type: 'numbers' },
                            { field: 'UserCode', minWidth: 200, title: '科目编码' },
                            { field: 'FullName', minWidth: 200, title: '科目名称' },
                            { field: 'BalanceTotal', title: '余额' },
                            { field: 'AtypeInnerIndex',  80, align: 'center', title: '排序号' },
                            { field: 'TypeId',  80, align: 'center', title: 'ID' },
                            { field: 'ParId',  80, align: 'center', title: '父级ID' },
                        ]],
                        done: function () {
                            layer.closeAll('loading');
                        }
                    });
    
                    $('#btn-expand').click(function () {
                        treetable.expandAll('#auth-table');
                    });
    
                    $('#btn-fold').click(function () {
                        treetable.foldAll('#auth-table');
                    });
                });
            }
        })
        </script>
    </body>
    </html>
    View Code

    4、控制器代码

    using MyWebSiteDemo.Models;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Script.Serialization;
    
    namespace MyWebSiteDemo.Controllers
    {
        public class MyTestController : Controller
        {
            public ActionResult Index()
            {
               return View();
            }
    
            public string GetDataSource() {
                ItemDbContext itemContext = new ItemDbContext();
                List<Item> list = itemContext.Database.SqlQuery<Item>("exec P_Inf_GetAtypeAssistantBalance").ToList();
                JsonData jsonData = new JsonData();
                jsonData.data = list;
                jsonData.code = "0";
                jsonData.msg = "OK";
                jsonData.count = "67";
                StringBuilder sb = new StringBuilder();
                JavaScriptSerializer json = new JavaScriptSerializer();
                json.Serialize(jsonData, sb);
                return sb.ToString();
            }
        }
    
        public class JsonData {
            public List<Item> data { get; set; }
            public string code { get; set; }
            public string msg { get; set; }
            public string count { get; set; }
        }
    
    }
    View Code

    5、实体代码

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace MyWebSiteDemo.Models
    {
        public class Item
        {
            /// <summary>
            /// 大类编号
            /// </summary>
            public string AtypeIndex { get; set; }
            //标识
            public int Tag { get; set; }
            /// <summary>
            /// 编码
            /// </summary>
            public string UserCode { get; set; }
            /// <summary>
            /// 全名
            /// </summary>
            public string FullName { get; set; }
            /// <summary>
            /// 编号
            /// </summary>
            public string TypeId { get; set; }
            /// <summary>
            /// 父级编号
            /// </summary>
            public string ParId { get; set; }
            /// <summary>
            /// 余额
            /// </summary>
            public decimal BalanceTotal { get; set; }
            /// <summary>
            /// 级别
            /// </summary>
            public int Leveal { get; set; }
            /// <summary>
            /// 排序
            /// </summary>
            public long AtypeInnerIndex { get; set; }
    
        }
    }
    View Code

    6、数据上下文

    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Linq;
    using System.Web;
    
    namespace MyWebSiteDemo.Models
    {
        public class ItemDbContext:DbContext
        {
            public ItemDbContext() : 
                base("数据库Key") {}
        }
    }
    View Code

    7、资源下载

    treetable插件  提取码:  6pjw

    写写博客,方便自己也方便有需要的人~~

  • 相关阅读:
    python中a = a+b与a += b的不同
    python中的全局变量global
    python中星号(*)和双星号(**)的用法
    python循环语句
    python逻辑运算符
    python内置函数 print()
    python 解析迅雷下载链接
    python 正则表达式
    python 读写文件
    python selenium操作cookie
  • 原文地址:https://www.cnblogs.com/Yisijun/p/13208388.html
Copyright © 2011-2022 走看看