我试图为我的公司报告财务数据:
我实际上有两张桌子:
___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)
感谢您的帮助。
答案 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