2017-02-07 2 views
0

私は毎日1回、別のテーブルを挿入するために1つのテーブルからレコードを選択する必要があるクエリを持っています(Select Into)。それは私がそれを1つのクエリをしたいので、私にとって大きな、十分な複雑なクエリです。ここで私は(それは多くの内部変数で参加して、グループいる)を変更するクエリの一部は次のとおりです。サブクエリーとパフォーマンスの問題での集計関数

Select RIGHT('0'+LTRIM(DATEDIFF(MINUTE,MIN(CASE WHEN [EnteranceDevice] IN(1) 
THEN CAST(EventDate as datetime) ELSE NULL END),(Select Cast([Start] as time) 
as Start FROM [dbo].[Period] Where strDay=DATEPART(dw,CAST('2017-01-30' as date)) 
And Timezone=[dbo].[Timezone].Timezone))/60),2) +':'+ 
RIGHT('0'+LTRIM(DATEDIFF(MINUTE,MIN(CASE WHEN [EnteranceDevice] IN(1) 
THEN CAST(EventDate as datetime) ELSE NULL END),(Select Cast([Start] as time) as Start 
FROM [dbo].[Period] Where strDay=DATEPART(dw,CAST('2017-01-30' as date)) 
And Timezone=[Timezone].Timezone))%60),2) AS WorkingHours from [dbo].[Events] 

このクエリは動作し、それが返します1時25分の時間を、このような答えを与えます。 [EnteranceDevice] IN(1)を[EnteranceDevice] IN([SPS]。[dbo] .UsersからReaderInputを選択)に変更すると、「集計またはサブクエリを含む式に対して集計関数を実行できません」というエラー

  1. どうすればこの問題を解決できますか?
  2. ReaderInput(nvarchar(50))は1つ以上のデバイスIDを格納する必要があるため、(1レコードで) '1,3,5'の値を持ちますが、EnteranceDeviceはintです。だからキャスティング(Cast(EnteranceDevice as nvarchar(50)) IN(...))が使えますか?
  3. 私のコードで多くのパフォーマンスの問題が発生していると思います。クエリに関する推奨事項を聞きたい。

答えて

0

何かが参加左言うように同じ同じで、ターゲットがnullではないので、次のようにリファクタリングが容易な「中」であると言って...覚えている:

はあなたのコードを読むことができませんでした再フォーマットする必要がありましたそれは何らかのロジックを持っています....

Select 
    RIGHT(
    '0'+LTRIM(DATEDIFF(MINUTE,MIN(CASE WHEN [EnteranceDevice] IN(1) THEN CAST(EventDate as datetime) ELSE NULL END), 
    (Select Cast([Start] as time) as Start FROM [dbo].[Period] Where strDay=DATEPART(dw,CAST('2017-01-30' as date)) And Timezone=[dbo].[Timezone].Timezone))/60), 
    2 
) + 
    ':'+ 
    RIGHT(
    '0'+LTRIM(DATEDIFF(MINUTE,MIN(CASE WHEN [EnteranceDevice] IN(1) THEN CAST(EventDate as datetime) ELSE NULL END), 
    (Select Cast([Start] as time) as Start FROM [dbo].[Period] Where strDay=DATEPART(dw,CAST('2017-01-30' as date)) And Timezone=[Timezone].Timezone))%60), 
    2) AS WorkingHours 
from [dbo].[Events] 

まず、あなたは同じサブクエリを2回持っています。今

Select 
    RIGHT('0'+LTRIM(DATEDIFF(MINUTE,MIN(CASE WHEN [EnteranceDevice] IN(1) THEN CAST(EventDate as datetime) ELSE NULL END),x.start)/60),2) + 
    ':'+ 
    RIGHT('0'+LTRIM(DATEDIFF(MINUTE,MIN(CASE WHEN [EnteranceDevice] IN(1) THEN CAST(EventDate as datetime) ELSE NULL END),x.start)%60),2) AS WorkingHours 
from [dbo].[Events] 
cross join (
    Select Cast([Start] as time) as Start 
    FROM [dbo].[Period] 
    Where strDay=DATEPART(dw,CAST('2017-01-30' as date)) 
    And Timezone=[Timezone].Timezone 
) x 

に参加するユーザーに参加クロスにそれを引き出して、ヌルのために迅速な応答を

Select 
    RIGHT('0'+LTRIM(DATEDIFF(MINUTE,MIN(CASE WHEN u.ReaderInput is not null THEN CAST(EventDate as datetime) ELSE NULL END),x.start)/60),2) + 
    ':'+ 
    RIGHT('0'+LTRIM(DATEDIFF(MINUTE,MIN(CASE WHEN u.ReaderInput is not null THEN CAST(EventDate as datetime) ELSE NULL END),x.start)%60),2) AS WorkingHours 
from [dbo].[Events] 
left join [SPS].[dbo].Users u on [EnteranceDevice] = u.ReaderInput 
cross join (
    Select Cast([Start] as time) as Start 
    FROM [dbo].[Period] 
    Where strDay=DATEPART(dw,CAST('2017-01-30' as date)) 
    And Timezone=[Timezone].Timezone 
) x 
+0

感謝を確認してください。私はすべての2つのサブクエリを修正します。 [EnteranceDevice]と[ReaderInput]については何かがあります。 [EnteranceDevice]はintで、1,2,4,6などの整数値を取得します。[ReaderInput]はnvarchar(50)であり、値は '2,3,5'または '4'だけです。ですから、[EnteranceDevice]がNULLではないのですか? EnteranceDeviceの値はReaderInput列にある必要があります。 – Murat

+0

おそらく '[EnteranceDevice] = u.ReaderInput'が同じ型を比較していない場合、一方の側が他の型へのキャストに変更しなければならないかどうかは分かりません。これはあまり一般的ではありません - それらは同じタイプでなければならず、何かがあなたのデザインに非常に間違っています。 – Hogan

関連する問題