Sql-Server-2014

Insert Into with Select 在一次實例中有效,但在另一個實例中無效。子查詢錯誤或數據不正確

  • March 14, 2017

我正在嘗試編寫一個腳本,該腳本將根據調查中使用的人口統計組合特定的調查結果。我已經能夠編寫一個腳本,將人口統計數據添加在一起以創建一個新的人口統計數據,例如 M18+ 和 F18+ = A18+,它完美地工作但是當嘗試創建一個將創建一個人口統計數據范圍的腳本時,例如 A18-24,我遇到了一些問題無法解決。

我的第一個將兩個人口統計圖相加的腳本如下:

create table #SurveyTemp
(
   Com nchar(6),
   Survey nvarchar(50),
   Demo nchar(50),
   Wk int,
   Time int,
   Aud decimal(18,8)
);

insert into #SurveyTemp (Com, Survey, Demo, Wk, Time, Aud)
select   Com, Survey, 'A18+', Wk, Time, sum(Aud)
from     table_survey
where    survey = 'LO2017'
and      demograph like 'F18+'
or       surveyid = 'LO2017'
and      demograph like 'M18+'
group by Com, survey, Wk, Time:

insert into table_survey
select temp.Com, temp.Survey, temp.Demo, temp.Wk, temp.Time, temp.Aud
from   #SurveyTemp temp

drop table #SurveyTemp

這個腳本工作正常。它將兩個人口統計圖加在一起並插入新的數據行,為每個 Com、Survey、Wk 和 Time 創建受眾總和。請參閱下面的範例數據集,其中 M18+ 和 F18+ 的添加創建了一個名為 A18+ 的新記錄

讓我從一個範例數據集開始:(免責聲明:實時數據庫中的每個人口統計數據都有很多行)

com | surveyid | demo | wk | time | audience
-------------------------
1 | LO2017    | A18+ | 1  | 300  |   4.7
1 | LO2017    | F18+ | 1  | 300  |   1.9
1 | LO2017    | M18+ | 1  | 300  |   2.8
1 | LO2017    | A25+ | 1  | 300  |   2.3
1 | LO2017    | A18+ | 2  | 100  |   3.7
1 | LO2017    | F18+ | 2  | 100  |   1.9
1 | LO2017    | M18+ | 2  | 100  |   2.8
1 | LO2017    | A25+ | 2  | 100  |   4.3

我現在需要編寫的是一個創建範圍的腳本。請注意上表中的 A18+ 和 A25+。請記住,在我的實時表格中,所有人口統計數據都會有 MULTIPLE 行。

在本例中,我將使用上表。因此,我需要創建一個類似的腳本,將兩個人口統計的受眾相加,然後從另一個中減去一個以創建一個範圍。例如,從 A18+ 中減去 A25+ 數據以創建稱為 A1824 的範圍。我希望這是有道理的。

在下面的腳本中,我試圖創建一個名為“A1824”的範圍,但我要麼收到“子查詢返回超過 1 行”錯誤,要麼將錯誤的數據插入到臨時表中,其中 AudOne 和 AudTwo 的總和是每個 Wk 和 Time 都相同。

create table #SurveyTemp
(
   Com nchar(6),
   Survey nvarchar(50),
   Demo nchar(50),
   Wk int,
   Time int,
   Aud decimal(18,8),
   AudOne decimal(18,8),
   AudTwo decimal(18,8)
);

insert into #SurveyTemp (Com, Survey, Demo, Wk, TimeBlock, Aud, AudOne, AudTwo)
(select   Com, Survey, 'A1824', Wk, Time, 0.0, 
         (select sum(aud) from table_survey where demo = 'A18+'), 
         (select sum(aud) from table_survey where demo = 'A25+')
from     table_survey 
where    surveyid = 'LO2017'
group by Com, survey, Wk, Time, 
)

update #SurveyTemp
set Aud = AudOne - AudTwo;

insert into table_survey
select temp.Com, temp.survey, temp.demo, temp.Wk, temp.Time, temp.aud
from   #SurveyTemp temp

drop table #SurveyTemp

這是我需要開始工作的第二個腳本,並且花了幾個小時試圖解決,但運氣不佳。如果我能提供更多資訊來幫助你,請告訴我!

編輯:我的預期結果將如下所示:

com | surveyid | demo  | wk | time | audience
-------------------------
1  | LO2017   | A1824 | 1  | 300  |   2.4

但是會有多個行,其中有多個“wk”和“time”條目。例如:

com | surveyid | demo  | wk | time | audience
-------------------------
1  | LO2017   | A1824 | 1  | 100  |   2.4
1  | LO2017   | A1824 | 1  | 200  |   3.7
1  | LO2017   | A1824 | 2  | 100  |   2.1
1  | LO2017   | A1824 | 2  | 200  |   6.2

我將在您生成#SurveyTemp 表後開始。

我不確定是否理解您的預期結果,請查看您按展示訂購的表格:

SELECT   * 
FROM     @table_survey  
WHERE    demo IN ('A18+','A25+') 
ORDER BY com, survey_id, demo, wk;

com | survey_id | demo | wk | time | audience | 
--: | :-------- | :--- | -: | ---: | :------- | 
 1 | LO2017    | A18+ |  1 |  300 | 4.7      | 
 1 | LO2017    | A18+ |  2 |  100 | 3.7      | 
 1 | LO2017    | A25+ |  1 |  300 | 2.3      | 
 1 | LO2017    | A25+ |  2 |  100 | 4.3      |

每個展示有 2 條記錄。如果您想通過這兩條記錄之間的某些操作來添加新記錄,您應該決定是否要按 wk 和 time 分組(我認為這是正確的方式)。

在您的插入命令中:

insert into #SurveyTemp (Com, Survey, Demo, Wk, TimeBlock, Aud, AudOne, AudTwo)
(select   Com, Survey, 'A1824', Wk, Time, 0.0, 
         (select sum(aud) from table_survey where demo = 'A18+'), 
         (select sum(aud) from table_survey where demo = 'A25+')
from     table_survey 
where    surveyid = 'LO2017'
group by Com, survey, Wk, Time, 
)

您按 分組Com, Survey, Wk, Time,但您正在計算所有展示記錄的總體受眾(不考慮周和時間):

(select sum(aud) from table_survey where demo = 'A18+')
(select sum(aud) from table_survey where demo = 'A25+')

恕我直言,至少wk應該將其添加到新記錄中,並且您應該決定如何處理時間。

我建議的解決方案:GROUP BY WK AND TIME

SELECT   Com, survey_id, 'A1824', wk, time,
        (SELECT sum(audience) FROM @table_survey 
         WHERE demo = 'A18+' AND wk = t1.wk AND time = t1.time)
         - 
        (SELECT sum(audience) FROM @table_survey 
         WHERE demo = 'A25+' AND wk = t1.wk AND time = t1.time) AS audience
FROM     @table_survey t1
WHERE    survey_id = 'LO2017'
GROUP BY Com, survey_id, Wk, time;

注意:我已經為每個展示添加了wktime計算sum(audience)

Com | survey_id | (No column name) | wk | time | audience
--: | :-------- | :--------------- | -: | ---: | :-------
 1 | LO2017    | A1824            |  1 |  300 | 2.4     
 1 | LO2017    | A1824            |  2 |  100 | -0.6    

如您所見,第一條記錄符合您的預期結果。

沒有按周和時間分組

SELECT   Com, survey_id, 'A1824', 0 AS wk,
        avg(time) as time,
        (SELECT sum(audience) FROM @table_survey WHERE demo = 'A18+')
         - 
        (SELECT sum(audience) FROM @table_survey WHERE demo = 'A25+') AS audience
FROM     @table_survey t1
WHERE    survey_id = 'LO2017'
GROUP BY Com, survey_id;

這是結果:

Com | survey_id | (No column name) | wk | time | audience
--: | :-------- | :--------------- | -: | ---: | :-------
 1 | LO2017    | A1824            |  0 |  200 | 1.8     

注意:您不需要 INSERT & UPDATE,它可以在單個 INSERT 操作中完成。

檢查它:*這裡*的 dbfiddle

引用自:https://dba.stackexchange.com/questions/167084