2016-07-01 11 views
3

テーブルスキーマ:最速の方法

CREATE TABLE [dbo].[VMaster](
    [VID] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL, 
    [VName] [varchar](30) NOT NULL 
) 
GO 

CREATE TABLE [dbo].[TblMaster](
    [SID] [int] IDENTITY(1,1) NOT NULL Primary Key, 
    [VID] [int] NOT NULL, 
    [CreatedDate] [datetime] default (getdate()) NOT NULL, 
    [CharToAdd] [varchar](10) NOT NULL, 
    [Start] [int] NOT NULL, 
    [End] [int] NOT NULL 
) ON [PRIMARY] 
GO 

CREATE TABLE [dbo].[TblDetails](
    [DetailsID] [int] IDENTITY(1,1) NOT NULL Primary Key, 
    [SID] [int] NOT NULL, 
    [Sno] [int] NOT NULL, 
    [ConcatenatedText] [varchar](20) NOT NULL, 
    [isIssued] [bit] default (0) NOT NULL, 
    [isUsed] [bit] default (0) NOT NULL 
) 
GO 

ALTER TABLE [dbo].[TblMaster] WITH CHECK ADD CONSTRAINT [fk_SI_id] FOREIGN KEY([VID]) 
REFERENCES [dbo].[VMaster] ([VID]) 
GO 

ALTER TABLE [dbo].[TblMaster] CHECK CONSTRAINT [fk_SI_id] 
GO 

サンプルデータ:

Insert into dbo.VMaster Values ('A1') 
Insert into dbo.VMaster Values ('A2') 
GO 

Insert into dbo.TblMaster Values (1,default, 'ABC', 1, 5) 
Insert into dbo.TblMaster Values (1,default, 'XYZ', 10, 20) 
Insert into dbo.TblMaster Values (2,default, 'P1', 10, 15) 
GO 

Insert into dbo.TblDetails values(1, 1, 'ABC1', 1,0) 
Insert into dbo.TblDetails values(1, 2, 'ABC2', 1,0) 
Insert into dbo.TblDetails values(1, 3, 'ABC3', 1,0) 
Insert into dbo.TblDetails values(1, 4, 'ABC4', 0,0) 
Insert into dbo.TblDetails values(1, 5, 'ABC5', 0,0) 
Insert into dbo.TblDetails values(2, 10, 'XYZ10', 1,0) 
Insert into dbo.TblDetails values(2, 11, 'XYZ11', 1,0) 
Insert into dbo.TblDetails values(2, 12, 'XYZ12', 1,0) 
Insert into dbo.TblDetails values(2, 13, 'XYZ13', 1,0) 
Insert into dbo.TblDetails values(2, 14, 'XYZ14', 1,0) 
Insert into dbo.TblDetails values(2, 15, 'XYZ15', 0,0) 
Insert into dbo.TblDetails values(2, 16, 'XYZ16', 0,0) 
Insert into dbo.TblDetails values(2, 17, 'XYZ17', 0,0) 
Insert into dbo.TblDetails values(2, 18, 'XYZ18', 0,0) 
Insert into dbo.TblDetails values(2, 19, 'XYZ19', 0,0) 
Insert into dbo.TblDetails values(2, 20, 'XYZ20', 0,0) 
Insert into dbo.TblDetails values(3, 10, 'P110', 1,0) 
Insert into dbo.TblDetails values(3, 11, 'P111', 1,0) 
Insert into dbo.TblDetails values(3, 12, 'P112', 1,0) 
Insert into dbo.TblDetails values(3, 13, 'P113', 1,0) 
Insert into dbo.TblDetails values(3, 14, 'P114', 1,0) 
Insert into dbo.TblDetails values(3, 15, 'P115', 1,0) 
    GO 

予想される出力:

enter image description here

012私は今のよう持って

問合せ:私はそのisIssued値である0

  1. ユーザーは期間を選択することができ、各VIDのためにTblDetailsで総一致するレコードを計算しようとしています

    SELECT 
        TM.VID, VM.VName, TM.CharToAdd, TM.Start, TM.[End], 
        (SELECT COUNT(*) FROM dbo.TblDetails TD where TD.SID=TM.SID and isIssued = 0) Balance 
    FROM 
    dbo.TblMaster TM, dbo.VMaster VM 
    Where VM.VID = TM.VID 
    

    この出力を表示する日付範囲(日付範囲)。 TblMaster.CreatedDateは、これを使用する必要があります。

  2. また、特定のVIDを選択してその結果のみを表示することもできます。
  3. 日付範囲またはVIDが指定されていない場合は、テーブル全体に対して機能する必要があります。 1か月あたりTblDetailsに500000件のレコードがあり、12ヶ月分のデータが保存されます。
+1

データがあなたのやっていることをサポートしていないようです。詳細には、concatフィールドには、同じSID上のABCレコードとXYZレコードが表示されます。 IsIssued = 1の子テーブルに合計8個のレコードがあり、これがクエリの返すレコードです。私は何が欠けていますか?どのように2つを取得するのですか?連結してABCのレコードを数えるだけでも、2つではなく3つあります... –

+1

「それは機能していません」とはどういう意味ですか?エラーメッセージを含めます。 –

+0

@JoeCそれについては申し訳ありません。私のサンプルデータにはタイプミスがあります。今更新する予定です。 – prasanth

答えて

3

テーブル全体の要約については、クエリは正常に見えます。

オプションのフィルタリングを追加するのは簡単です。

パラメータがNULLの場合、無視されます。パラメータがNULLない場合は、結果セットを制限します:dbo.TblMaster.CreatedDatedbo.TblMaster.VID

CREATE NONCLUSTERED INDEX [IX_] ON [dbo].[TblDetails] 
(
    [isIssued] ASC, 
    [SID] ASC 
) 

もインデックス:それは効率的にするために

DECLARE @ParamStart datetime = '2016-01-01'; 
DECLARE @ParamEnd datetime = '2017-01-01'; 
DECLARE @ParamVID int = NULL; 

SELECT 
    TM.VID, VM.VName, TM.CharToAdd, TM.Start, TM.[End], 
    (SELECT COUNT(*) FROM dbo.TblDetails TD where TD.SID=TM.SID and isIssued = 0) Balance 
FROM 
    dbo.TblMaster AS TM 
    INNER JOIN dbo.VMaster AS VM ON VM.VID = TM.VID 
WHERE 
    (TM.CreatedDate >= @ParamStart OR @ParamStart IS NULL) 
    AND (TM.CreatedDate < @ParamEnd OR @ParamEnd IS NULL) 
    AND (TM.VID = @ParamVID OR @ParamVID IS NULL) 
ORDER BY TM.SID 
OPTION(RECOMPILE); 

を、それがこのインデックスを持つように助けるべきです。

+0

あなたの提案をありがとう。誤字脱字して申し訳ありません。今私のクエリは期待された結果を返すようです。巨大なテーブルを打ったときにどちらが優れているかをテストするにはどうすればよいですか? – prasanth

+0

パフォーマンスをテストする方法は1つしかありません。「巨大な」テーブルに対してクエリを実行し、ストップウォッチを使って時間を測定します。 –

+0

これに参加するときに 'AND(TM.VID = @ParamVID OR @ParamVID IS NULL)'を追加すると、データをより高速にフィルタリングするのにも役立ちますか? –

関連する問題