我有2张桌子
Payment_Schedule_Master
[PAYMENT_SCHEDULE_MASTER_ID] [int] NOT NULL, Primary key [FPI_ID] [varchar](9) NOT NULL, [DELETE_FLAG] [char](1) NOT NULL, [CREATED_BY] [varchar](30) NOT NULL, [CREATED_DATE] [datetime] NOT NULL, [MODIFY_BY] [varchar](30) NOT NULL, [MODIFY_DATE] [datetime] NOT NULL
Payment_Schedule_Detail
[PAYMENT_SCHEDULE_DETAIL_ID] [int] IDENTITY(1,1) NOT NULL, Primary key [PAYMENT_SCHEDULE_MASTER_ID] [int] NOT NULL, Foreign key to master table [PAY_YEAR] [int] NOT NULL, [PAY_MONTH] [int] NOT NULL, [ACTUAL] [money] NULL, [FORECAST] [money] NULL, [DELETE_FLAG] [char](1) NOT NULL, [CREATED_BY] [varchar](30) NOT NULL, [CREATED_DATE] [datetime] NOT NULL, [MODIFY_BY] [varchar](30) NOT NULL, [MODIFY_DATE] [datetime] NOT NULL
两者之间存在一对多的关系:Master
有一个条目,detail
有很多条。 Payment_Schedule_Detail
有一个id
,外键,实际,预测和许多列。实际和预测将包含数值。
问题:
我希望获得Payment_Schedule_Master
和Actual
等于0的ForeCast
行。
我的查询:
我试过了这个查询
Select
t.PAYMENT_SCHEDULE_MASTER_ID, psm.FPI_ID,
t.ActualSum, t.ForecastSum
from
(Select
SUM(Actual) As ActualSum,
SUM (forecast) AS ForecastSum,
PAYMENT_SCHEDULE_MASTER_ID
from
[dbo].[PAYMENT_SCHEDULE_DETAIL]
group by
PAYMENT_SCHEDULE_MASTER_ID) t
Inner Join
dbo.PAYMENT_SCHEDULE_MASTER psm on psm.PAYMENT_SCHEDULE_MASTER_ID = t.PAYMENT_SCHEDULE_MASTER_ID
where
t.ActualSum = t.ForecastSum
and t.ActualSum = 0
此查询的问题在于,如果Actual
在1月份为200,在12月份为200,则会选择该标题,因为SUM (Actual)
将为0,这是错误的。
我不知道如何修改查询,它应该只获得实际为0且预测为0的标题。
测试
如果有人会让我知道如何测试该方法?
更新:尝试了此查询,但需要8秒钟。
Select
t.PAYMENT_SCHEDULE_MASTER_ID, psm.FPI_ID,
t.ActualSum, t.ForecastSum, psd.ACTUAL, psd.FORECAST
from
(Select
SUM(Actual) As ActualSum, SUM (forecast) AS ForecastSum,
PAYMENT_SCHEDULE_MASTER_ID
from
[dbo].[PAYMENT_SCHEDULE_DETAIL]
group by
PAYMENT_SCHEDULE_MASTER_ID) t
Inner Join
dbo.PAYMENT_SCHEDULE_MASTER psm on psm.PAYMENT_SCHEDULE_MASTER_ID = t.PAYMENT_SCHEDULE_MASTER_ID
Inner Join
[dbo].[PAYMENT_SCHEDULE_DETAIL] psd on psm.PAYMENT_SCHEDULE_MASTER_ID = psd.PAYMENT_SCHEDULE_MASTER_ID
where
t.ActualSum = t.ForecastSum
and t.ActualSum = 0
and psd.ACTUAL = 0
order by
psm.FPI_ID
数据和输出:
psm_id Actual ForeCast [other columns]
900 10000.00 0.00
900 -10000.00 0.00
900 0.00 0.00
912 0.00 0.00
912 0.00 0.00
912 0.00 0.00
psm_id = Payment_Schedule_Master_ID
Payment_Schedule_Master_Id 900
实际总和为0,不应出现在结果上。但是912
会出现在结果中,因为所有记录都是0.我希望这会有所帮助。
答案 0 :(得分:3)
怎么样 -
select * from Payment_Schedule_Master
where NOT EXISTS
(
SELECT null FROM Payment_Schedule_Detail
where (forecast != 0 or actual != 0) and
Payment_Schedule_Master.id = PAYMENT_SCHEDULE_MASTER_ID
)
注意,这也会找到Payment_Schedule_Master,它没有任何相关的payment_schedule_details行。
答案 1 :(得分:0)
要测试你可以使用像SQL Fiddle这样的东西。
尝试this
我尝试以下SQL
select *
from Payment_Schedule_Master mast
where ((select sum(actual) from Payment_Schedule_Detail where main = mast.id) = 0)
and ((select sum(forecast) from Payment_Schedule_Detail where main = mast.id) = 0)
它更简单,我认为它可以满足您的需求
答案 2 :(得分:0)
Select
t.PAYMENT_SCHEDULE_MASTER_ID, psm.FPI_ID,
t.ActualSum, t.ForecastSum, psd.ACTUAL, psd.FORECAST
from
(Select t1.ActualSum,t1.ForecastSum,t1.PAYMENT_SCHEDULE_MASTER_ID
from
(Select
SUM(Actual) As ActualSum, SUM (forecast) AS ForecastSum, PAYMENT_SCHEDULE_MASTER_ID
from
[CILS].[dbo].[PAYMENT_SCHEDULE_DETAIL]
group by
PAYMENT_SCHEDULE_MASTER_ID) t1
where
t1.ActualSum = 0 and t1.ForecastSum=0)t
Inner Join
[Cils].dbo.PAYMENT_SCHEDULE_MASTER psm on psm.PAYMENT_SCHEDULE_MASTER_ID = t.PAYMENT_SCHEDULE_MASTER_ID
Inner Join
[CILS].[dbo].[PAYMENT_SCHEDULE_DETAIL] psd on psm.PAYMENT_SCHEDULE_MASTER_ID = psd.PAYMENT_SCHEDULE_MASTER_ID
order by
psm.FPI_ID
答案 3 :(得分:0)
您的原始查询非常接近您的需求。您正在寻找实际和预测始终为零的情况。好吧,如果它们总是0,那么绝对值之和为0.所以试试这个:
Select
t.PAYMENT_SCHEDULE_MASTER_ID, psm.FPI_ID,
t.ActualAbsSum, t.ForecastAbsSum
from
(Select
SUM(abs(Actual)) As ActualAbsSum,
SUM(abs(forecast)) AS ForecastAbsSum,
PAYMENT_SCHEDULE_MASTER_ID
from
[dbo].[PAYMENT_SCHEDULE_DETAIL]
group by
PAYMENT_SCHEDULE_MASTER_ID) t
Inner Join
dbo.PAYMENT_SCHEDULE_MASTER psm on psm.PAYMENT_SCHEDULE_MASTER_ID = t.PAYMENT_SCHEDULE_MASTER_ID
where
t.ForecastAbsSum = 0 and t.ActualAbsSum = 0
您是否想要获得0的任何示例,如:
Select psm.*
from dbo.PAYMENT_SCHEDULE_MASTER psm
where psm.PAYMENT_SCHEDULE_MASTER_ID in (select PAYMENT_SCHEDULE_MASTER_ID
from [PAYMENT_SCHEDULE_DETAIL]
where actual = 0 and forecast = 0
)
为了清楚起见,它使用in
而不是join
(两者都在SQL Server引擎中以相同的方式实现)。
答案 4 :(得分:0)
在我看来,在您总结之前,您需要在“实际”和“预测”列中使用哪个位置:
Select
t.PAYMENT_SCHEDULE_MASTER_ID, psm.FPI_ID,
t.ActualSum, t.ForecastSum
from
(Select
SUM(Actual) As ActualSum,
SUM (forecast) AS ForecastSum,
PAYMENT_SCHEDULE_MASTER_ID
from
[dbo].[PAYMENT_SCHEDULE_DETAIL]
where Actual=0 and forecast=0
group by
PAYMENT_SCHEDULE_MASTER_ID) t
Inner Join
dbo.PAYMENT_SCHEDULE_MASTER psm on psm.PAYMENT_SCHEDULE_MASTER_ID = t.PAYMENT_SCHEDULE_MASTER_ID
话虽如此,如果性能是一个问题,你不需要SUM实际和预测,因为你总结了零。然后我们可以做得更简单:
Select
t.PAYMENT_SCHEDULE_MASTER_ID, psm.FPI_ID, 0 as ActualSum, 0 as ForecastSum
from
(Select distinct
PAYMENT_SCHEDULE_MASTER_ID
from
dbo.PAYMENT_SCHEDULE_DETAIL
where Actual=0 and forecast=0 ) t
Inner Join
dbo.PAYMENT_SCHEDULE_MASTER psm
On psm.PAYMENT_SCHEDULE_MASTER_ID = t.PAYMENT_SCHEDULE_MASTER_ID
我在性能优化方面并不太聪明 - 如果你的子查询产生很多行,那么在加入前选择不同的行,如上所述,可能会更快。但你可以试试这个:
Select distinct
psd.PAYMENT_SCHEDULE_MASTER_ID, psm.FPI_ID, 0 as ActualSum, 0 as ForecastSum
from
dbo.PAYMENT_SCHEDULE_DETAIL psd
Inner Join
dbo.PAYMENT_SCHEDULE_MASTER psm
On
psm.PAYMENT_SCHEDULE_MASTER_ID = psd.PAYMENT_SCHEDULE_MASTER_ID
Where
Actual=0 and forecast=0
哪个更简单,但在过滤不同的行之前加入行可能会更慢。并且,不要忘记将FK编入索引,除非您正在进行大量数据写入。
答案 5 :(得分:0)
我相信这就是你要找的东西:
SELECT M.*
FROM Payment_Schedule_Detail D
JOIN Payment_Schedule_Master M
ON M.PAYMENT_SCHEDULE_MASTER_ID = D.PAYMENT_SCHEDULE_MASTER_ID
GROUP BY D.PAYMENT_SCHEDULE_MASTER_ID
HAVING SUM(D.Actual) = 0 AND SUM(D.Forecast) = 0
或者这个:
SELECT M.*
FROM (SELECT PAYMENT_SCHEDULE_MASTER_ID,
SUM(Actual) ActualSum, SUM(Forecast) ForecastSum
FROM Payment_Schedule_Detail
GROUP BY PAYMENT_SCHEDULE_MASTER_ID) D
JOIN Payment_Schedule_Master M
ON M.PAYMENT_SCHEDULE_MASTER_ID = D.PAYMENT_SCHEDULE_MASTER_ID
WHERE ActualSum = 0 AND ForecastSum = 0
不确定哪一个在性能方面更好。我认为第二个会创建一个临时表,因此速度较慢,但它可能取决于优化器。
根据您使用的SQL数据库类型,外键可能会或可能不会自动编入索引,如果不是,则应将索引编入索引。
答案 6 :(得分:0)
SELECT psm_id, ActualSum, ForecastSum FROM
(SELECT
PAYMENT_SCHEDULE_MASTER_ID AS psm_id, SUM(psd.Actual) As ActualSum, SUM (psd.forecast) AS ForecastSum
FROM
[dbo].[PAYMENT_SCHEDULE_DETAIL] psd, dbo.PAYMENT_SCHEDULE_MASTER psm
GROUP BY PAYMENT_SCHEDULE_MASTER_ID
) ts, dbo.PAYMENT_SCHEDULE_MASTER psm1
WHERE psm1.PAYMENT_SCHEDULE_MASTER_ID = ts.psm_id
AND ts.ActualSum = 0 AND ts.ForecastSum
ORDER BY
psm1.FPI_ID
答案 7 :(得分:0)
谢谢你的答案,但它根本没有用。
在我的数据库中有一个我没看到的特例。如果特定Payment_Schedule_Id的实际和预测都为0,那么它只有一行。
Select PAYMENT_SCHEDULE_MASTER_ID from (
Select COUNT(*) As IdCount, PAYMENT_SCHEDULE_MASTER_ID, ACTUAL , FORECAST
from PAYMENT_SCHEDULE_DETAIL
group by PAYMENT_SCHEDULE_MASTER_ID, ACTUAL, FORECAST) t
where t.IdCount = 1
and t.ACTUAL = 0.00
and t.FORECAST = 0.00
以上是解决方案。