这个复杂工作的查询是什么?

时间:2013-04-20 06:52:04

标签: sql-server

我有以下表格

Materials Groups
-------------------------------
|GrpID | GrpName | GrpParentID |
-------------------------------

Materials
--------------------------------------
|MatID | MatName | MatGroupID |Price |
--------------------------------------

Stores
-----------------------------
|StID | StName | StParentID |
-----------------------------

BillType
--------------------
|TypeID | TypeName |
--------------------

这些是

类型
Store Out
Store In/Price
Sales Return
First Period Inventory
Sales
End Period Inventory
Store Out/Price
Purchase
Store In
Ready Product In
Purchase Return
Sales Return1
Raw Materials Out

Bills
----------------------------------
|BillID | BillType| Client..|....|
----------------------------------

BillItems
---------------------------------
|ItemID| MatID| quantity|BillID |
---------------------------------

要求是以此表格显示报告 the report design

我认为这是一个很大的失误,我不知道该怎么做

我尝试了加入,支点,但我得到了不完整的报告,我认为这是非常复杂的

这是我最近的尝试

declare @table1 table
(
    MatGUID uniqueidentifier,
    TypeGUID uniqueidentifier,
    Qty int
)
declare @table2 table
(
    MatGroup varchar(250),
    MatName varchar(250),
    BillTypeName varchar(250),
    Qty int
)
insert into @table1
select fatoraitem.MatGUID, fatora.TypeGUID, SUM(fatoraitem.Qty) as Qty
from bi000 fatoraitem
left join bu000 as fatora on fatora.GUID = fatoraitem.ParentGUID
left join bt000 as fatoratype on fatoratype.GUID = fatora.TypeGUID
group by fatoraitem.MatGUID, fatora.TypeGUID


insert into @table2
select gr000.Name as MatGroup, mt000.Name MatName, bt000.Name as BillTypeName, t1.Qty from @table1 t1
left join mt000 on mt000.GUID = t1.MatGUID
left join bt000 on bt000.GUID = t1.TypeGUID
left join gr000 on mt000.GroupGUID = gr000.GUID

declare
    @StoreCols nvarchar(max),
    @BillTypeCols nvarchar(max),
    @stmt nvarchar(max)

select @BillTypeCols = isnull(@BillTypeCols + ', ', '') + '[' + T.BillTypeName + ']' from (select distinct BillTypeName from @table2) as T

IF OBJECT_ID('tempdb..#Results') IS NOT NULL
    DROP TABLE #Results
select * into #Results from @table2
select @stmt = 'select * from #results as T
        pivot 
        (
            sum(T.Qty)
            for T.BillTypeName in (' + @BillTypeCols + ')
        ) as P'

exec sp_executesql  @stmt

1 个答案:

答案 0 :(得分:0)

我不知道为什么人民会投票?而不是编辑问题,提供评论建议或回答人们投票的问题。

我终于解决了它没有解决100%它是90%,换句话说,商店积累不起作用[它计算商店中材料的数量,但对于父母商店它不总和儿童商店] 这是sql

create PROCEDURE [dbo].[AdvancedBillMatReport]
@ParamUserGuid AS UNIQUEIDENTIFIER = NULL,
@ParamMaterialguid AS UNIQUEIDENTIFIER = 0X0,
@ParamGroupLevel AS int = 0,
@ParamStoreGuid AS UNIQUEIDENTIFIER = 0X0,
@ParamDisplayType AS int = 1,
@ParamPriceType AS int = 0, 
@ParamBillTypesGuidsStr AS varchar(max)  = NULL
AS
SET NOCOUNT ON
IF OBJECT_ID('tempdb..#Result') IS NOT NULL
    DROP TABLE #Result
IF OBJECT_ID('tempdb..#Results') IS NOT NULL
    DROP TABLE #Results
IF OBJECT_ID('tempdb..#SecViol') IS NOT NULL
    DROP TABLE #SecViol
IF OBJECT_ID('tempdb..#SecViols') IS NOT NULL
    DROP TABLE #SecViols
CREATE TABLE [#SecViol] (Type [INT], Cnt [INT])
CREATE TABLE [#SecViols] (Type [INT], Cnt [INT])
--BILLTYPES
declare @BillTYpesGuids table
(
    TypeGUID uniqueidentifier,
    TypeName varchar(250)
)
insert into @BillTYpesGuids
select t1.GUID AS TypeGUID, bt000.Name AS TypeName from splitstring ( @ParamBillTypesGuidsStr, ';' ) t1 left join bt000 on bt000.GUID = t1.GUID

--MATRIALS the actual vertical part of thetable
declare @Materials table
(
    MatGUID uniqueidentifier,
    GroupGuid uniqueidentifier,
    Code varchar(250),
    Name varchar(250),
    LatinName varchar(250),
    [Level] int,
    [Path] [VARCHAR](8000),
    [Type] int
)
insert into @Materials
exec  repMattreeReport

--/////////////FILTER MATERIALS///////////////////////////////
DELETE FROM @Materials WHERE (Level < @ParamGroupLevel)
IF @ParamMaterialguid <> 0X0
BEGIN
    DELETE FROM @Materials WHERE MatGUID <> @ParamMaterialguid
END
SELECT * INTO #Result FROM @Materials
exec prcCheckSecurity @ParamUserGuid
DELETE FROM @Materials WHERE MatGUID NOT IN (SELECT MatGUID FROM #Result)
DROP TABLE #Result
INSERT INTO #SecViols SELECT * FROM #SecViol
TRUNCATE TABLE #SecViol
--/////////////DONE FILTERING//////////////////////////

--STORES the repeated Horizontal parts of table
declare @stores table
(
    StoreGuid uniqueidentifier,
    Name varchar(250),
    ParentGUID uniqueidentifier,
    Level int
)
insert into @stores(StoreGuid, Name, ParentGUID, Level)
SELECT T1.GUID AS StoreGuid, st000.Name, st000.ParentGUID, T1.Level FROM fnGetStoresListTree(@ParamStoreGuid, 1) AS T1 LEFT JOIN st000 ON T1.GUID = st000.GUID 

--/////////////FILTER STORES///////////////////////////

SELECT * INTO #Result1 FROM @stores
exec prcCheckSecurity @ParamUserGuid,0,0,'#Result1'
DELETE FROM @stores WHERE StoreGuid NOT IN (SELECT StoreGuid FROM #Result1)
DROP TABLE #Result1
INSERT INTO #SecViols SELECT *FROM #SecViol
TRUNCATE TABLE #SecViol
--/////////////DONE FILTERING//////////////////////////

--the grouped bill items
declare @MatData table
(
    MatGUID uniqueidentifier,
    StoreGUID uniqueidentifier,
    TypeGUID uniqueidentifier,
    GroupGuid uniqueidentifier,
    Qty int
)
insert into @MatData
select fatoraitem.MatGUID, fatoraitem.StoreGUID, fatora.TypeGUID, mada.GroupGUID, ISNULL(SUM(fatoraitem.Qty),0) as Qty
from bi000 fatoraitem
left join bu000 as fatora on fatora.GUID = fatoraitem.ParentGUID
left join mt000 as mada on mada.GUID = fatoraitem.MatGUID
group by fatoraitem.MatGUID, fatoraitem.StoreGUID, fatora.TypeGUID, mada.GroupGUID

INSERT INTO @Materials([Type], MatGUID, GroupGuid, Name,Path) VALUES(2, 0X0, 0X0, 'المجموع الكلي', (SELECT MAX(PATH) FROM @Materials))--FOR THE TOTAL
SELECT [Type], [Level], MatGUID, GroupGuid, Name INTO #ResultS FROM @Materials ORDER BY Path

DECLARE SelectedBillTypes CURSOR LOCAL FOR
SELECT TypeGUID, TypeName FROM @BillTYpesGuids

DECLARE STORESITERATOR CURSOR LOCAL FOR
SELECT StoreGuid, Name FROM @STORES

DECLARE MatIterator CURSOR LOCAL FOR
SELECT MatGuid, Name, Level, Type FROM @Materials

OPEN SelectedBillTypes--BILLS-TYPES
    DECLARE @TypeGuid UNIQUEIDENTIFIER
    DECLARE @TypeName varchar(250)
    FETCH NEXT FROM SelectedBillTypes into @TypeGuid, @TypeName
    WHILE(@@FETCH_STATUS = 0)
        BEGIN
            OPEN STORESITERATOR--STORES
                DECLARE @StoreGuid UNIQUEIDENTIFIER
                DECLARE @StoreName varchar(250)
                FETCH NEXT FROM STORESITERATOR into @StoreGuid, @StoreName
                WHILE(@@FETCH_STATUS = 0)
                BEGIN
                    DECLARE @ColumnQName VARCHAR(MAX)
                    DECLARE @ColumnPName VARCHAR(MAX)
                    DECLARE @AlterStatement VARCHAR(MAX)
                    set @ColumnQName = '[' + @TypeName + '.' + @StoreName + '.Q]'
                    SET @AlterStatement = 'ALTER TABLE #Results ADD ' + @ColumnQName + ' INT NOT NULL DEFAULT(0)'
                    Execute(@AlterStatement)
                    IF(@ParamDisplayType = 1)--EXPANED DISPLAY
                    BEGIN
                        set @ColumnPName = '[' + @TypeName + '.' + @StoreName + '.P]'
                        SET @AlterStatement = 'ALTER TABLE #Results ADD ' + @ColumnPName + ' INT NOT NULL DEFAULT(0)'
                        Execute(@AlterStatement)
                    END
                    OPEN MatIterator--MATS AND GROUPS
                    DECLARE @MatGuid uniqueidentifier, @MatName varchar(250), @MatLevel int, @MatType int
                    FETCH NEXT FROM MatIterator INTO @MatGuid, @MatName, @MatLevel, @MatType
                    WHILE(@@FETCH_STATUS = 0)
                    BEGIN
                        DECLARE @Price INT, @Quantity INT
                        DECLARE @InsertStatement varchar(MAX)

                        select @Price = CASE WHEN @ParamPriceType = 0X4 THEN Whole
                                             WHEN @ParamPriceType = 0x8 THEN Half
                                             WHEN @ParamPriceType = 0x10 THEN Export
                                             WHEN @ParamPriceType = 0x20 THEN Vendor
                                             WHEN @ParamPriceType = 0x40 THEN Retail
                                             WHEN @ParamPriceType = 0x80 THEN EndUser
                                        END
                                        from mt000 where GUID = @MatGuid
                        IF @MatType = 1
                            SELECT @Quantity = ISNULL(SUM(Qty), 0) FROM @MatData AS T1 WHERE (T1.MatGUID = @MatGUID AND T1.StoreGUID = @StoreGuid And T1.TypeGUID = @TypeGuid)
                        ELSE
                            SET @Quantity = 0
                        set @Price = @Price * @Quantity
                        SET @InsertStatement = 'UPDATE #Results SET ' + @ColumnQName + ' = ' + CAST(@Quantity as VARCHAR(50)) 
                        IF(@ParamDisplayType = 1)--EXPANED DISPLAY
                        BEGIN
                            SET @InsertStatement += ', ' + @ColumnPName + ' = ' + CAST(@Price AS VARCHAR(50))
                        END
                        SET @InsertStatement +=   ' WHERE MatGUID = ''' + CAST(@MatGuid AS VARCHAR(50)) + ''''
                        EXECUTE(@InsertStatement)
                        FETCH NEXT FROM MatIterator INTO @MatGuid, @MatName, @MatLevel, @MatType
                    END
                    CLOSE MatIterator
                    DECLARE @UpdateStatemENT VARCHAR(MAX)
                    DECLARE @Total VARCHAR(MAX)
                    DECLARE @MaxLevel INT
                    SELECT @MaxLevel = ISNULL(MAX(Level),0) FROM #ResultS
                    SET @Total = 'UPDATE #ResultS SET ' + @ColumnQName + ' = ' +
                                '(SELECT ISNULL(SUM(' + @ColumnQName + '), 0) FROM #ResultS AS T2 WHERE T2.Type = 1)'
                    IF(@ParamDisplayType = 1)--EXPANED DISPLAY
                    BEGIN
                        SET @Total += ', ' + @ColumnPName + ' = ' + '(SELECT ISNULL(SUM(' + @ColumnPName + '), 0) FROM #ResultS AS T2 WHERE T2.Type = 1) '
                    END
                    SET @Total +=' WHERE [TYPE] = 2'
                    EXECUTE(@Total)

                    WHILE (@MaxLevel>-1)
                    BEGIN
                        SET @UpdateStatemENT = 'UPDATE #ResultS SET ' + @ColumnQName + ' = ' +
                                               '(SELECT ISNULL(SUM(' + @ColumnQName + '), 0) FROM #ResultS AS T2 WHERE T2.GroupGuid = #ResultS.MatGUID)'
                        IF(@ParamDisplayType = 1)--EXPANED DISPLAY
                        BEGIN
                            SET @UpdateStatemENT += ', ' + @ColumnPName + ' = ' + '(SELECT ISNULL(SUM(' + @ColumnPName + '), 0) FROM #ResultS AS T2 WHERE T2.GroupGuid = #ResultS.MatGUID) '
                        END
                        SET @UpdateStatemENT += ' WHERE [TYPE] = 0 AND Level = ' + CAST(@MaxLevel AS VARCHAR(50))
                        EXECUTE(@UpdateStatemENT)
                        set @MaxLevel -= 1
                    END
                    FETCH NEXT FROM STORESITERATOR into @StoreGuid, @StoreName
                END
            CLOSE STORESITERATOR
            FETCH NEXT FROM SelectedBillTypes into @TypeGuid, @TypeName
        END
CLOSE SelectedBillTypes
SELECT * FROM #ResultS

这是结果 enter image description here

表头是在c ++中构建的,我从列名称列名称= billtypename.storename.q获取数量,或者获取价格的billtypename.storename.p。在c ++中,我遍历表中的列名并拆分它们并处理标题 在表格中我把它们放在来自服务器的