加入表并从此新表中计算百分比

时间:2017-03-16 18:25:20

标签: mysql

我试图为我的公司报告财务数据:

我实际上有两张桌子:

___BillableDatas

|--------|------------|----------|----------|--------------|---------------------|
| BIL_Id | BIL_Date   | BIL_Type | BIL_Rate | BIL_Quantity | BIL_ApplicableTaxes |
|--------|------------|----------|----------|--------------|---------------------|
| 1      | 2017-01-01 | Night    | 95       | 1            | 1                   |
| 2      | 2017-01-02 | Night    | 95       | 1            | 1                   |
| 3      | 2017-01-15 | Night    | 105      | 1            | 1                   |
| 4      | 2017-01-15 | Item     | 8        | 2            | 1,2                 |
| 5      | 2017-02-14 | Night    | 95       | 1            | 1                   |
| 6      | 2017-02-15 | Night    | 95       | 1            | 1                   |
| 7      | 2017-02-16 | Night    | 95       | 1            | 1                   |
| 8      | 2017-03-20 | Night    | 89       | 1            | 1                   |
| 9      | 2017-03-21 | Night    | 89       | 1            | 1                   |
| 10     | 2017-03-21 | Item     | 8        | 3            | 1,2                 |
|--------|------------|----------|----------|--------------|---------------------|

___SalesTaxes

|--------|------------|
| STX_Id | STX_Amount |
|--------|------------|
| 1      | 14.00      |
| 2      | 5.00       |
|--------|------------|

我每个月都需要知道有税和无税的收入总和。

实际上我可以制作报告,但不知道如何循环到___SalesTaxes表。

我实际上有什么:

SELECT month(BIL_Date) AS month,
sum(BIL_Rate * BIL_Quantity) AS sumval
FROM `___BillableDatas`
WHERE BIL_Date BETWEEN "2017-01-01" AND "2017-12-31"
AND BIL_Type = "Night" OR BIL_Type = "Item"
GROUP BY year(BIL_Date), month(BIL_Date)

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

正如kbball提到的,你在主表中有很多未解决的关系。绝不应将适当的表设计为每个字段具有多个值。解决多对多关系非常简单。您需要创建一个类似于bill_taxType的新表或类似的关系。新表将有两个字段以及标准主键,它将具有bill_id和适用的税号。对于新表中的1,2字段(如bill id 4),它将看起来像

primary key,  bill id,  applicable tax id
1             4         1
2             4         2

在您的最终查询中,您将在适当的主键 - 外键关系上将所有三个一起加入。最终查询应该包含您需要的数据。

答案 1 :(得分:0)

这将有效,我创建的以下示例将帮助您进行调试和实施。尝试实现如下:

If(OBJECT_ID('tempdb..#___BillableDatas') Is Not Null)
Begin
    Drop Table #___BillableDatas
End
If(OBJECT_ID('tempdb..#___SalesTaxes') Is Not Null)
Begin
    Drop Table #___SalesTaxes
End

CREATE TABLE #___BillableDatas
(
    BIL_Id INT IDENTITY (1,1),
    BIL_Date DATETIME,
    BIL_Type VARCHAR(50),
    BIL_Rate FLOAT,
    BIL_Quantity INT,
    BIL_ApplicableTaxes VARCHAR(10)
);

INSERT INTO #___BillableDatas (BIL_Date,BIL_Type,BIL_Rate,BIL_Quantity,BIL_ApplicableTaxes) 
VALUES  ('2017-01-01','Night',95,1,'1'),
        ('2017-01-02','Night',95,1,'1'),
        ('2017-01-15','Night',105,1,'1'),
        ('2017-01-15','Item',8,2,'1,2'),
        ('2017-02-14','Night',95,1,'1'),
        ('2017-02-15','Night',95,1,'1'),
        ('2017-02-16','Night',95,1,'1'),
        ('2017-03-20','Night',89,1,'1'),
        ('2017-03-21','Night',89,1,'1'),
        ('2017-03-21','Item',8,1,'1,2')

CREATE TABLE #___SalesTaxes
(
    STX_Id INT IDENTITY (1,1),
    STX_Amount FLOAT
);
INSERT INTO #___SalesTaxes (STX_Amount) VALUES (14.00),(5.00)

-----------------------------------------------------------------

SELECT * FROM #___BillableDatas
SELECT * FROM #___SalesTaxes


SELECT MONTH(BD.BIL_Date) AS [Month],SUM(BD.BIL_Rate * BD.BIL_Quantity) AS 'Without Tax'
,(SUM(BD.BIL_Rate * BD.BIL_Quantity)+((SUM(BD.BIL_Rate * BD.BIL_Quantity)/100)*BD.Tax1)) AS 'With Tax 1'
,(SUM(BD.BIL_Rate * BD.BIL_Quantity)+((SUM(BD.BIL_Rate * BD.BIL_Quantity)/100)*BD.Tax2)) AS 'With Tax 2'
FROM 
(
SELECT *,
(SELECT ST1.STX_Amount FROM Func_Split(BIL_ApplicableTaxes,',') AS F LEFT JOIN #___SalesTaxes AS ST1 ON F.Element=ST1.STX_Id WHERE F.Element='1') AS Tax1 ,
(SELECT ST1.STX_Amount FROM Func_Split(BIL_ApplicableTaxes,',') AS F LEFT JOIN #___SalesTaxes AS ST1 ON F.Element=ST1.STX_Id WHERE F.Element='2') AS Tax2
FROM #___BillableDatas) AS BD
WHERE BD.BIL_Date BETWEEN '2017-01-01' AND '2017-12-31' AND BD.BIL_Type = 'Night' OR BD.BIL_Type = 'Item'
GROUP BY YEAR(BD.BIL_Date), MONTH(BD.BIL_Date),BD.Tax1,BD.Tax2

上面的解决方案需要函数Func_Split,请使用:

CREATE FUNCTION [dbo].[func_Split] 
    (   
    @DelimitedString    varchar(8000),
    @Delimiter              varchar(100) 
    )
RETURNS @tblArray TABLE
    (
    ElementID   int IDENTITY(1,1),  -- Array index
    Element     varchar(1000)               -- Array element contents
    )
AS
BEGIN

    -- Local Variable Declarations
    -- ---------------------------
    DECLARE @Index      smallint,
                    @Start      smallint,
                    @DelSize    smallint

    SET @DelSize = LEN(@Delimiter)

    -- Loop through source string and add elements to destination table array
    -- ----------------------------------------------------------------------
    WHILE LEN(@DelimitedString) > 0
    BEGIN

        SET @Index = CHARINDEX(@Delimiter, @DelimitedString)

        IF @Index = 0
            BEGIN

                INSERT INTO
                    @tblArray 
                    (Element)
                VALUES
                    (LTRIM(RTRIM(@DelimitedString)))

                BREAK
            END
        ELSE
            BEGIN

                INSERT INTO
                    @tblArray 
                    (Element)
                VALUES
                    (LTRIM(RTRIM(SUBSTRING(@DelimitedString, 1,@Index - 1))))

                SET @Start = @Index + @DelSize
                SET @DelimitedString = SUBSTRING(@DelimitedString, @Start , LEN(@DelimitedString) - @Start + 1)

            END
    END

    RETURN
END
相关问题