0

誰か助けてくれませんか?SQL クエリを作成しようとしていますが、2 ~ 3 日間問題が発生しています。最初に問題を定義させてください。

私は2つのテーブルを持っています

  1. Payment_Schedule_Master
    [PAYMENT_SCHEDULE_MASTER_ID] [int] NOT NULL、主キー
    [FPI_ID] [varchar](9) NOT NULL、
    [DELETE_FLAG] [char](1) NOT NULL、
    [CREATED_BY] [varchar](30) NOT NULL、
    [作成日] [日時] NOT NULL、
    [MODIFY_BY] [varchar](30) NOT NULL、
    [MODIFY_DATE] [日時] NOT NULL
  1. Payment_Schedule_Detail
    [PAYMENT_SCHEDULE_DETAIL_ID] [int] IDENTITY(1,1) NOT NULL、主キー
    [PAYMENT_SCHEDULE_MASTER_ID] [int] NOT NULL、マスター テーブルへの外部キー
    [PAY_YEAR] [int] NOT NULL、
    [PAY_MONTH] [int] NOT NULL、
    [実際] [お金] NULL、
    [FORECAST] [お金] NULL,
    [DELETE_FLAG] [char](1) NOT NULL、
    [CREATED_BY] [varchar](30) NOT NULL、
    [作成日] [日時] NOT NULL、
    [MODIFY_BY] [varchar](30) NOT NULL、
    [MODIFY_DATE] [日時] NOT NULL

2 つの間には 1 対多の関係があります。つまり、 Master1 つのエントリがあり、複数のエントリdetailがあります。Payment_Schedule_Detailid外部キー、実績、予測、および多数の列があります。実績と予測には数値が含まれます。

問題: 0に等しい行
を取得したい。Payment_Schedule_MasterActualForeCast

私のクエリ:

このクエリを試しました

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 になります。結果には表示されません。すべてのレコードが9120 だったので、結果に表示されます。これがお役に立てば幸いです。

4

8 に答える 8

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_details 行を持たない Payment_Schedule_Master も検索することに注意してください。

于 2012-12-27T15:47:35.873 に答える
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

パフォーマンスの点でどちらが優れているかわかりません。2つ目は一時テーブルを作成するため、速度が低下すると思いますが、おそらくオプティマイザーに少し依存します。

使用しているSQLデータベースのタイプに応じて、外部キーは自動的にインデックス付けされる場合とされない場合があります。そうでない場合は、外部キーにインデックスを付ける必要があります。

于 2013-01-08T21:16:17.833 に答える
0

テストするには、SQL Fiddle などを使用できます。

これを試してください

次の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)

それはより簡単で、あなたが望むものになると思います

于 2012-12-27T10:46:10.013 に答える
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
于 2012-12-27T10:47:21.307 に答える
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
于 2013-01-10T18:03:02.287 に答える
0

回答ありがとうございますが、まったく機能していませんでした。

私のデータベースには、見たことのない特別なケースが 1 つあります。特定の Payment_Schedule_Id の実績と予測の両方が 0 の場合、行は 1 つしかありません。

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

以上が解決策でした。

于 2013-01-11T16:44:36.300 に答える
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に a の代わりに を使用joinしています (SQL Server エンジンでは、どちらもほぼ同じように実装されています)。

于 2012-12-27T14:43:55.103 に答える
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

とはいえ、パフォーマンスが問題になる場合は、ゼロを合計しているため、実績と予測を合計する必要はありません。次に、より簡単に行うことができます。

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 のインデックスを作成することを忘れないでください。

于 2013-01-08T13:11:15.863 に答える