2013-07-23 12 views
0

我是SQL新手,使用時間有限,所以請客氣。我已經編寫過NPR,並且在NPR中編寫代碼,但是我擁有SQL的基本知識,並且SQL可以是一種不同類型的野獸。我喜歡通過這種方式來學習,並且已經在這幾天磕磕絆絆了,現在我打電話給大槍!我已經在StackOverflow上閱讀了許多文章,並且非常喜歡你的社區如何協同工作,找到解決方案,幫助那些迴應並幫助他人的人們做得不錯(或不會)。無論如何,我只是不能想出我需要的數據來獲取我需要的數據。我查看了大量的帖子,閱讀了一堆,並處理了一些子查詢,其他人處理了DISTINCT,而其他人加入,但我還沒有看到可以解決我遇到的問題。一切工作正常,但以下例外:只顯示一個帳號及其回覆和日期

  1. 我不能得到愚蠢的列標題的子查詢打印。
  2. 我不能找出規則顯示只有1個帳戶與其迴應和日期。
  3. 算的#2 大一個分子爲#2

規則:1。 我只能有一個帳戶的日期範圍內,無論顯示有多少了。 2.我必須記錄訪問的響應,如果有1個響應將其添加到分子並採取該特定日期。變化的日期與「1」的迴應無關緊要,只捕獲其中的一個。因此,例如,如果有5個帳號具有相同的UnitNumber,3個響應爲「1」,2個響應爲「0」,則只抓取其中一個「1」的日期並增加分子;否則如果他們都是0只顯示其中一個帳戶但不增加分子。 3.我必須記錄回覆的日期。

因此,例如:下面M000003206該帳戶應當只顯示一次,並且響應值應爲1與13年1月3日的日期和分母應13.

* M000003206 1 1/03/2011應顯示在數據中,並填寫分子 * M000003206 0 1/04/2011不應出現在數據中,而不在分母或分子中。

注意: - 「響應」是一個跟蹤一堆查詢6000左右的字段。 C.AD.DOCS部分可以有5個我不關心的答案,我只是想看看他們是否迴應了他們,如果是的話就扔1;如果沒有答案響應是0. - 我還沒有寫分子的一部分,因爲我不知道如何使規則限制帳戶只顯示1次訪問 - 此外,我得到一個沒有列名稱列出,我已經看着,但我不能似乎找到如何糾正這一個子查詢

的分子(一次寫入)應該是7,對於所有這些1.

BTW的迴應:我有變化單元號和承認保護機密數據的日期。

謝謝你的回覆!

OUTPUT --------------------------------------------- ----------------

分母14

UnitNumber沒有列名沒有列名

M000001058 2011年1月4日

M000004955 2011年1月3日

M000006362 2011年1月3日

M000006211 2011年1月3日

M000004212 2011年1月3日

M000009850 1/03/2011

M000003047 2011年1月4日

* M000003206 1/03/2011 *

* M000003206 1/04/2011 *

M000002526 1/04/2011

M000000538 1/04/2011

M000003813 2011年1月3日

M000004473 2011年1月4日

M000004794 1 2011年1月3日

 Should be Should be 
     Response AdmitDate 

CODE ----- -------------------------------------------------- ------------

use livedb 
    DECLARE @StartDate DateTime, 
    @EndDate DateTime 

    SET @StartDate = '1/03/2011 00:00:00.000' 
    SET @EndDate = '1/05/2011 00:00:00.000' 
    SELECT DISTINCT COUNT(UnitNumber) AS Denominator 
    FROM AbstractData 
    WHERE (AbstractData.AdmitDateTime BETWEEN @StartDate and @EndDate) 
      and (AbstractData.BirthDateTime < '1946-09-29 00:00:00.000') 
      and (AbstractData.PtStatus IN ('IN','INO')) 
    SELECT DISTINCT AbstractData.UnitNumber AS UnitNumber, 
    (SELECT MAX(CASE WHEN AbsQueriesMult.GroupResponse = 'C.AD.DOCS' THEN 1 ELSE 0 END) AS Response 
    FROM AbsQueriesMult WHERE AbstractData.AbstractID = AbsQueriesMult.AbstractID), 
    (SELECT CONVERT(VARCHAR(12),AbstractData.AdmitDateTime,101) AS AdmitDate) 
    FROM AbstractData 
    WHERE (AbstractData.AdmitDateTime BETWEEN @StartDate and @EndDate) 
      and (AbstractData.BirthDateTime < '1946-09-29 00:00:00.000') 
      and (AbstractData.PtStatus IN ('IN','INO')) 
    ORDER BY UnitNumber 

+0

閱讀完第一段後,我真的很想幫忙,但是很難完全按照你的所有細節。如果你將問題歸結爲仍然存在你所關心的所有問題的最小問題,那對我們其他人將會非常有幫助。如果這仍然是一個大問題,請將問題分解成更小的塊。 SQLFiddle也很有幫助。如果可以,請使用簡化的模式和樣本數據創建一個。 –

回答

0

我會先解決簡單的問題。標記子查詢的語法是:

select (subquery) as label1, (subquery) as label2 

對於您的例子,它是:

SELECT DISTINCT AbstractData.UnitNumber AS UnitNumber, 
(SELECT MAX(CASE WHEN AbsQueriesMult.GroupResponse = 'C.AD.DOCS' THEN 1 ELSE 0 END) 
FROM AbsQueriesMult WHERE AbstractData.AbstractID = AbsQueriesMult.AbstractID) AS Response, 
CONVERT(VARCHAR(12),AbstractData.AdmitDateTime,101) AS AdmitDate 
FROM AbstractData 
WHERE (AbstractData.AdmitDateTime BETWEEN @StartDate and @EndDate) 
     and (AbstractData.BirthDateTime < '1946-09-29 00:00:00.000') 
     and (AbstractData.PtStatus IN ('IN','INO')) 
ORDER BY UnitNumber 

我也是從AdmitDate刪除SELECT因爲它是沒有必要的。只是從你的查詢中清除一些東西。

現在是令人困惑的部分。

讓我總結一下我認爲你的問題是什麼。你有一個表/視圖/無論AbstractData。 AbstractData有很多字段,但是對你的問題最有意思的是AdmitDateTime,UnitNumber和你計算的字段Response。你想列出所有UnitNumbers。對於每個UnitNumber,如果任何一行有1,則返回值應爲1,否則爲0.從所有這些UnitNumbers中,您希望總計數爲分母,並且1的數目爲Numerator。

所以我認爲這將是很好的做到這一步。在第一步中,我們將裝飾與計算字段響應和AdmitDate你的所有行:

SELECT AbstractData.UnitNumber AS UnitNumber, 
(SELECT MAX(CASE WHEN AbsQueriesMult.GroupResponse = 'C.AD.DOCS' THEN 1 ELSE 0 END) 
FROM AbsQueriesMult WHERE AbstractData.AbstractID = AbsQueriesMult.AbstractID) AS Response, 
SELECT CONVERT(VARCHAR(12),AbstractData.AdmitDateTime,101) AS AdmitDate 
FROM AbstractData 
WHERE (AbstractData.AdmitDateTime BETWEEN @StartDate and @EndDate) 
     and (AbstractData.BirthDateTime < '1946-09-29 00:00:00.000') 
     and (AbstractData.PtStatus IN ('IN','INO')) 

此查詢獲取所有重複的。現在我們將刪除重複項。

爲此,我們將按照UnitNumber對行進行分區。在每個UnitNumber中,我們將訂購Response DESC。我們只需要每個組的第一個響應。

不幸的是,這不是一個簡單的操作。我希望你使用SQL Server,因爲你的查詢看起來像TSQL。我也希望你使用2005+爲ROW_NUMBER。我們將首先在分區中標記每行的排名。然後我們將只選擇第一個響應。

SELECT * FROM (
    SELECT *, 
     ROW_NUMBER() OVER (PARTITION BY UnitNumber ORDER BY Response DESC) as r 
    FROM (
     SELECT AbstractData.UnitNumber AS UnitNumber, 
     (SELECT MAX(CASE WHEN AbsQueriesMult.GroupResponse = 'C.AD.DOCS' THEN 1 ELSE 0 END) 
     FROM AbsQueriesMult WHERE AbstractData.AbstractID = AbsQueriesMult.AbstractID) AS Response, 
     SELECT CONVERT(VARCHAR(12),AbstractData.AdmitDateTime,101) AS AdmitDate 
     FROM AbstractData 
     WHERE (AbstractData.AdmitDateTime BETWEEN @StartDate and @EndDate) 
       and (AbstractData.BirthDateTime < '1946-09-29 00:00:00.000') 
       and (AbstractData.PtStatus IN ('IN','INO')) 
    ) Decorated 
) Labeled 
WHERE r = 1 

現在,你有這樣的結果,也有你可以用它來得到分母和分子的幾種方法。您可以將其存儲在臨時表或表變量中,也可以複製並粘貼查詢兩次,一次列出所有行並一次執行聚合(分子和分母)。您也可以使用CTE來爲表格別名,以便用分子和分母修飾所有返回的行。這是很多冗餘信息,但可能意味着更快的查詢時間。你必須嘗試一下。祝你好運。

+0

John,謝謝你的回覆! M000214955 \t \t 0 10/3/2011 M000312526 \t \t \t 0 2011年10月4日 M000236362 \t \t \t 1 10/3/2011 M000370538 \t \t \t 1 2011年10月4日 M000246211 \t \t \t 1 10/3/2011 M000373813 \t \t \t 0 10/3/2011 M000254212 \t \t \t 0 10/3/2011 M000384473 \t \t \t 1 2011年10月4日 M000273047 \t \t \t 0 2011年10月4日 M000259850 \t \t \t 1 10/3/2011 M000384794 \t \t \t 1 10/3/2011 M000211058 \t \t \t 1 2011年10月4日 M000273206 \t 2011年10月4日\t 1 <<< @JohnTseng – Rich

+0

對不起,讓這個竅門..不知道回報的職位。再次感謝您的快速開機,我成功地運行它,它發佈的數據,但其拉動的0而不是1第二個響應的響應,所以M000273206 0 2011年10月4日1 <<<應該真正顯示它拉動響應1和其10/03/2011日期應爲M000273206 1 10/3/2011 – Rich

+0

@Rich對不起。我有一個錯字。我在我們要ORDER BY響應DESC的描述中提到的,但是我在代碼中留出了DESC。 –

相關問題