2017-04-06 19 views
0

Problem Illustration 要約情報を生成するためにその魔法のクエリを探しています。私は自分の問題を架空のイラストレーションにマッピングしました。私は数年かけてホテルの部屋で漏れが記録された 'WaterLeakage%'テーブルを持っています。SQLクエリのヘルプが必要 - 1番目のテーブルの複数の行が2番目のテーブルの複数のテーブルと一致する必要があります

私は、各テーブルのWaterConsumptionをリットルで記録する別のテーブルを持っています。

ここで、所定の期間にわたって所定の部屋番号で実際の水漏れをリットルで見つけなければなりません。

基本的に私は 'WaterLossage'テーブルのいくつかの行を 'WaterConsumption'テーブルのいくつかの行にグループ化する必要があります。私はこれを見つけるために魔法の効率的なクエリを把握しようとしています。見つけられない、助けてください。

答えて

0
BEGIN 
    --Input Parameters for calculating water wastage between date range 
    DECLARE @START_DATE_PARAM DATE = '01/10/2017'; 
    DECLARE @END_DATE_PARAM DATE = '01/31/2017'; 

    --Table for daily daily water consumption per room 
    CREATE TABLE #WATER_CONSUMPTION(
    ROOM_NUMBER INT, 
    UDAY DATE, 
    WATER_CONSUMPTION_LITER INT 
    ) 

    --Table for water leakage percent per room for date range 
    CREATE TABLE #WATER_LEAKAGE_PER 
    (
    ROOM_NUMBER INT, 
    START_DATE DATE, 
    END_DATE DATE, 
    WATER_LEAKAGE_PERCENT INT, 
    LEAKAGE_PER_DAY_IN_LITER INT 
    ) 

    -- Leakage in liter per room for each day, This will have multiple entries for room and date if room number and date is available in multiple date ranges, ex. in #WATER_CONSUMPTION table for room number 101 we have multiple entries with overlapping dates 
    CREATE TABLE #DAY_WISE_LEAKAGE 
    (
    ROOM_NUMBER INT, 
    LDATE DATE, 
    LEAKAGE_IN_LITER INT 
    ) 


    -- Raw Data 
    INSERT INTO #WATER_LEAKAGE_PER(ROOM_NUMBER,START_DATE,END_DATE,WATER_LEAKAGE_PERCENT) 
    VALUES(101,'2017/01/15','2017/01/18',30), 
    (102,'2017/01/15','2017/01/18',10), 
    (101,'2017/01/15','2017/02/13',5); 

    -- Raw Data 
    INSERT INTO #WATER_CONSUMPTION 
    VALUES(101,'01/01/2017',1001), 
    (101,'01/02/2017',1001), 
    (101,'01/03/2017',1001), 
    (101,'01/04/2017',1001), 
    (101,'01/05/2017',1001), 
    (101,'01/06/2017',1001), 
    (101,'01/07/2017',1001), 
    (101,'01/08/2017',1001), 
    (101,'01/09/2017',1001), 
    (101,'01/10/2017',1001), 
    (101,'01/11/2017',1001), 
    (101,'01/12/2017',1001), 
    (101,'01/13/2017',1001), 
    (101,'01/14/2017',1001), 
    (101,'01/15/2017',1001), 
    (101,'01/16/2017',1001), 
    (101,'01/17/2017',1001), 
    (101,'01/18/2017',1001), 
    (101,'01/19/2017',1001), 
    (101,'01/20/2017',1001), 
    (101,'01/21/2017',1001), 
    (101,'01/22/2017',1001), 
    (101,'01/23/2017',1001), 
    (101,'01/24/2017',1001), 
    (101,'01/25/2017',1001), 
    (101,'01/26/2017',1001), 
    (101,'01/27/2017',1001), 
    (101,'01/28/2017',1001), 
    (101,'01/29/2017',1001), 
    (101,'01/30/2017',1001), 
    (101,'01/31/2017',1001); 



    DECLARE @ROOM_NUMBER INT 
    DECLARE @START_DATE DATE 
    DECLARE @END_DATE DATE 
    DECLARE @WATER_LEAKAGE_PERCENT INT 

    -- cursor for calculating water wastage pre date range per day available in #WATER_LEAKAGE_PER table 
    DECLARE WATER_LEAKAGE_PER_CURSOR CURSOR FOR 
    SELECT ROOM_NUMBER,START_DATE,END_DATE,WATER_LEAKAGE_PERCENT FROM #WATER_LEAKAGE_PER 

    OPEN WATER_LEAKAGE_PER_CURSOR 

    FETCH NEXT FROM WATER_LEAKAGE_PER_CURSOR 
    INTO @ROOM_NUMBER, @START_DATE ,@END_DATE, @WATER_LEAKAGE_PERCENT 

    WHILE @@FETCH_STATUS = 0 
    BEGIN 
      DECLARE @TOTAL_WATER_USED_FOR_DATE_RANGE INT=0; 
      DECLARE @NUMBER_OF_DAYS INT=0; 
      DECLARE @LEAKAGE_PER_DAY_IN_LITER INT=0; 

      -- Total Liters of water used for 1 date range 
      SELECT @TOTAL_WATER_USED_FOR_DATE_RANGE =SUM(WATER_CONSUMPTION_LITER),@NUMBER_OF_DAYS=COUNT(1) FROM #WATER_CONSUMPTION WHERE [email protected]_NUMBER AND UDAY BETWEEN @START_DATE AND @END_DATE; 

      -- Liters of water leakage per day for selevted date range in cursor 
      SELECT @LEAKAGE_PER_DAY_IN_LITER=((@TOTAL_WATER_USED_FOR_DATE_RANGE*@WATER_LEAKAGE_PERCENT)/100)/@NUMBER_OF_DAYS; 
      UPDATE #WATER_LEAKAGE_PER SET LEAKAGE_PER_DAY_IN_LITER = @LEAKAGE_PER_DAY_IN_LITER WHERE [email protected]_NUMBER AND START_DATE = @START_DATE AND [email protected]_DATE AND [email protected]_LEAKAGE_PERCENT; 

      -- generate dates and water leakage, this will be used for actual calculation of water leakage in date range. 
      ;WITH n AS 
      (
       SELECT TOP (DATEDIFF(DAY, @START_DATE, @END_DATE) + 1) 
       n = ROW_NUMBER() OVER (ORDER BY [object_id]) 
       FROM sys.all_objects 
      ) 
      INSERT INTO #DAY_WISE_LEAKAGE SELECT @ROOM_NUMBER, DATEADD(DAY, n-1, @START_DATE),@LEAKAGE_PER_DAY_IN_LITER 
      FROM n; 

    FETCH NEXT FROM WATER_LEAKAGE_PER_CURSOR 
     INTO @ROOM_NUMBER, @START_DATE ,@END_DATE, @WATER_LEAKAGE_PERCENT 
    END 
    CLOSE WATER_LEAKAGE_PER_CURSOR; 
    DEALLOCATE WATER_LEAKAGE_PER_CURSOR; 

    -- Average of Liters of water leakage per Room number. 
    SELECT ROOM_NUMBER,SUM(LEAKAGE_IN_LITER) FROM #DAY_WISE_LEAKAGE WHERE LDATE BETWEEN @START_DATE_PARAM AND @END_DATE_PARAM GROUP BY ROOM_NUMBER; 

    DROP TABLE #WATER_CONSUMPTION; 
    DROP TABLE #WATER_LEAKAGE_PER; 
    DROP TABLE #DAY_WISE_LEAKAGE 

    END 
+0

私はカーソルを使用せずにこれを解決できるかどうかを確認しようとしていたあなたの答えに非常に感謝します。 – Datha

+0

私はもう一度カーソルなしで変換しようとします。既に解決策がある場合は、私に知らせてください。 – Vidyadhar

+0

いいえ、私はまだ1つを見つけるのに苦労しています。 – Datha

1
DECLARE @START_DATE_PARAM DATE = '01/10/2017'; 
DECLARE @END_DATE_PARAM DATE = '01/31/2017'; 
DECLARE @ROOM_NUMBER INT = 101; 

IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '#WATER_CONSUMPTION')) 
    DROP TABLE #WATER_CONSUMPTION; 
IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '#WATER_LEAKAGE_PER')) 
    DROP TABLE #WATER_LEAKAGE_PER; 

--Table for daily daily water consumption per room 
CREATE TABLE #WATER_CONSUMPTION(
ROOM_NUMBER INT, 
UDAY DATE, 
WATER_CONSUMPTION_LITER INT 
) 

--Table for water leakage percent per room for date range 
CREATE TABLE #WATER_LEAKAGE_PER 
(
ROOM_NUMBER INT, 
START_DATE DATE, 
END_DATE DATE, 
WATER_LEAKAGE_PERCENT INT 
) 

-- Raw Data 
INSERT INTO #WATER_LEAKAGE_PER(ROOM_NUMBER,START_DATE,END_DATE,WATER_LEAKAGE_PERCENT) 
VALUES(101,'2017/01/01','2017/01/02',5), 
(102,'2017/01/01','2017/01/05',10), 
(101,'2017/01/04','2017/02/06',10); 

-- Raw Data 
INSERT INTO #WATER_CONSUMPTION 
VALUES(101,'2017/01/01',100), 
(101,'2017/01/02',100), 
(101,'2017/01/03',100), 
(101,'2017/01/04',100), 
(101,'2017/01/05',100), 
(101,'2017/01/06',100), 
(102,'2017/01/01',100), 
(102,'2017/01/02',100), 
(102,'2017/01/03',100), 
(102,'2017/01/04',100), 
(102,'2017/01/05',100); 

DECLARE @TotalLeak REAL = 0; 
SELECT * FROM #WATER_CONSUMPTION; 
SELECT * FROM #WATER_LEAKAGE_PER; 

SELECT * FROM #WATER_CONSUMPTION T1 JOIN (SELECT * FROM #WATER_LEAKAGE_PER WHERE [email protected]_NUMBER) T2 
ON (T1.ROOM_NUMBER=T2.ROOM_NUMBER AND T1.UDAY >= T2.START_DATE AND T1.UDAY <= T2.END_DATE); 

DROP TABLE #WATER_CONSUMPTION; 
DROP TABLE #WATER_LEAKAGE_PER; 

私は今、解決に非常に近いと思います。基本的に私は思考を変えました。私は今逆に参加します。

関連する問題