2017-06-25 1 views
0

私たちは4つの変数を受け取り、1つのint結果を返す関数を持っています。 テーブル内のすべてのレコードに対してこの関数を使いたいのですが、4つの変数は各レコードから取得します。sqlのループ内の関数をどのように集計できますか?

どうすれば解決できますか?

My機能:

CREATE FUNCTION dbo.occupiedDaysPerListingFunction(@CheckIn date, @CheckOut date, @Email varchar(80), @Title varchar(50)) 
      RETURNS int 
    AS 
    BEGIN 
    DECLARE @nightsInRange int 
    select @nightsInRange= (CASE 
    WHEN DATEDIFF(day,@CheckIn,getdate()) >0 and DATEDIFF(day,@CheckOut,getdate())+100 <0 THEN 100 
    WHEN DATEDIFF(day,@CheckIn,getdate()) >0 and DATEDIFF(day,@CheckOut,getdate())+100 >0 THEN DATEDIFF(day,getdate(),@CheckOut) 
    WHEN DATEDIFF(day,getdate(),@CheckIn) >0 and DATEDIFF(day,getdate(),@CheckIn) <100 and DATEDIFF(day,@CheckOut,getdate())+100 >0 THEN DATEDIFF(day,@CheckIn,@CheckOut) 
    WHEN DATEDIFF(day,getdate(),@CheckIn) >0 and DATEDIFF(day,getdate(),@CheckIn) <100 and DATEDIFF(day,@CheckOut,getdate())+100 <0 THEN DATEDIFF(day,@CheckIn,getdate())+100 
    WHEN DATEDIFF(day,@CheckIn,getdate()) <0 THEN 0 
END) 
FROM [dbo].[ORDERS] o 
     WHERE o.[E-mail] = @Email and o.[title][email protected] 
     RETURN @nightsInRange 
end 

enter image description here

+0

質問のタイトルに「sum」と記載されていますが、質問には表示されません。何故なの? – HABO

答えて

0

カーソルは、このタスクに適しただけのツールです。 Сursorは可能なオプションの1つです。

SELECT InnerQueryTable.OccupiedDaysPerListing FROM 
(
    SELECT 
     CheckInDate, 
     CheckOutDate, 
     Email, 
     Title, 
     dbo.occupiedDaysPerListingFunction(CheckInDate, CheckOutDate, Email, Title) AS OccupiedDaysPerListing 
    FROM 
     [YourDatabase].[YourSchema].[YourTable] 
) AS InnerQueryTable 
GO 
Rasmus Dybkjærの答え@に基づいて、あなたはこのようなSELECTクエリを絞り込むことができ

:あなたはまた、EDIT

DECLARE @iterator CURSOR 
DECLARE @bufferTable TABLE 
(
    CheckIn date, 
    CheckOut date, 
    Email varchar(80), 
    Title varchar(50) 
) 

SET @iterator = CURSOR FOR 
SELECT 
    CheckIn, 
    CheckOut, 
    Email, 
    Title 
FROM [YourDatabase].[YourSchema].[YourTable]  

OPEN @iterator 

FETCH NEXT FROM @iterator 
INTO @bufferTable 

WHILE @@FETCH_STATUS = 0 
BEGIN 

    /* Your function comes into play */ 
    dbo.occupiedDaysPerListingFunction(@bufferTable.CheckIn, @bufferTable.CheckOut, @bufferTable.Email, @bufferTable.Title) 

    FETCH NEXT FROM @iterator 
    INTO @bufferTable 
END; 

CLOSE @iterator 
DEALLOCATE @iterator 

GO 
などWHILE LOOP、CTEを使用することができます
0

私はあなたの関数が常に整数を返すようにしています。現在の関数は、[Orders]テーブルにメールとタイトルのフィルタを含むクエリを送信します。 [注文]表に同じメールとタイトルの複数の行が含まれている場合、どうなるべきかを考慮する必要があります。

CREATE FUNCTION dbo.occupiedDaysPerListingFunction(@CheckIn DATE, @CheckOut 
DATE, @Email VARCHAR(80), @Title VARCHAR(50)) 
RETURNS INT 
AS 
BEGIN 
    DECLARE @nightsInRange INT = 0; 
    SET @nightsInRange = (SELECT TOP 1 CASE 
     WHEN DATEDIFF(day,@CheckIn,getdate()) >0 and  DATEDIFF(day,@CheckOut,getdate())+100 <0 THEN 100 
     WHEN DATEDIFF(day,@CheckIn,getdate()) >0 and  DATEDIFF(day,@CheckOut,getdate())+100 >0 THEN DATEDIFF(day,getdate(),@CheckOut) 
     WHEN DATEDIFF(day,getdate(),@CheckIn) >0 and  DATEDIFF(day,getdate(),@CheckIn) <100 and DATEDIFF(day,@CheckOut,getdate())+100  >0 THEN DATEDIFF(day,@CheckIn,@CheckOut) 
     WHEN DATEDIFF(day,getdate(),@CheckIn) >0 and  DATEDIFF(day,getdate(),@CheckIn) <100 and DATEDIFF(day,@CheckOut,getdate())+100  <0 THEN DATEDIFF(day,@CheckIn,getdate())+100 
     WHEN DATEDIFF(day,@CheckIn,getdate()) <0 THEN 0 
     ELSE 0 
    END 
    FROM [dbo].[ORDERS] o 
    WHERE o.[E-mail] = @Email and o.[title][email protected]) 

    RETURN @nightsInRange 
END 

この機能はまだ完璧ではないですが、それはことを保証します:私はこのようなあなたの機能を書き換えで始まるでしょう

あなたの機能はすべての場合に値を返します 1)(レコードがない場合でも、見つかっ) 2)あなたの関数は、同じ電子メールとタイトル

で[受注]による複数に失敗しません。その後、私はこのようなクエリから、あなたの関数を呼び出します。

SELECT 
    CheckInDate, 
    CheckOutDate, 
    Email, 
    Title, 
    dbo.occupiedDaysPerListingFunction(CheckInDate, CheckOutDate, Email,  Title) AS OccupiedDaysPerListing 
FROM 
    [YourDatabase].[YourSchema].[YourTable] 

希望は役立ちます。

+0

原則として、「TOP」は「ORDER BY」とペアにする必要があります。この場合、どの行で実行されるかによって、予想される動作を説明するコメントを追加する価値があります。 'GetDate()'の各インスタンスはすべての行に対して単一の値を返しますが、異なるインスタンスは異なる値を返すことに注意してください。 1つの値を取得するのがベストプラクティスです(例: @NowをDateTime = GetDate();と宣言し、関数の残りの部分で変数 '@ Now'を使用します。 – HABO

+0

あなたのポイント@HABOに同意してください。これらはクエリの追加の改良になります。この場合、OrderDateで降順に注文したいと考えています。私。 ORDER BY [注文日] DESC' – dybzon

関連する問題