2016-08-08 37 views
1

我只需要在不重複的情況下獲得獨特的address_id。這是我的查詢。從sql數據集中刪除重複的address_id

SELECT DISTINCT address.address_id, address.address1, address.streetcity, state.stateabbrev, rtrim(ltrim(case when address.streetzipcode is not null and address.streetzipcode != 'NULL' then address.streetzipcode else '' end))+case when len(address.streetzipplus4)>0 then '-'+rtrim(ltrim(address.streetzipplus4)) else '' end as streetzipcode, address.homephone, 
     dbo.f_addressstudent (student.address_id) as Students, 
     dbo.f_addresspeople (student.address_id) as Adults, 
     case 
      when @classif_id IS NULL then 0 
      else 
      student.classif_id 
     end classif, 
     classifctn 
    FROM district WITH(NOLOCK) 
     JOIN dbo.building ON building.district_id = district.district_id 
     JOIN dbo.studbldg_bridge WITH(NOLOCK) ON studbldg_bridge.bldg_id=building.bldg_id 
     JOIN dbo.student WITH(NOLOCK) ON student.student_id = studbldg_bridge.student_id 
     JOIN classif with(nolock) on student.classif_id = classif.classif_id 
     LEFT JOIN dbo.address WITH(NOLOCK) ON student.address_id = address.address_id 
     LEFT JOIN dbo.state WITH(NOLOCK) ON address.streetstate_id = state.state_id 
     LEFT JOIN dbo.state AS mailstate WITH(NOLOCK) ON address.state_id = mailstate.state_id 
    WHERE district.district_id = (SELECT district_id FROM dbo.building WITH(NOLOCK) WHERE bldg_id = @bldg_id) 
    ORDER BY classif,Adults, Students 

這裏查詢 Query result with error in data

我已經試過組,使用聚合函數ADDRESS_ID但我也有非集合列,以便它並沒有爲我工作的結果。 之後,我也嘗試使用OVER(由address.address_id分區),但它也沒有奏效。

任何幫助將提前感激。

謝謝

**更新業務邏輯/需求**

我需要獲得唯一的地址爲學生的家長。由於父母可以有兩個或更多的孩子住在同一個地址,所以會導致重複。換句話說,我需要每個父母只有一個孩子。

+1

當有重複,應該如何分類(例如)是決心?如果沒有充分定義您的要求,就不可能得到「正確」的答案。 –

+0

我刪除了mysql標記,因爲如果您嘗試使用窗口函數OVER(分區....),這意味着您沒有使用它,因爲窗口函數不存在於mysql中。請僅標記您實際使用的rdbms。 – Matt

+0

我正在更新問題以向您提供有關需求的更多信息。 – NKhan

回答

0

從結果圖像看來,classifctn列的值超過1,因此它正在重複排序。爲了獲得1個不同的address_id和其餘列,可以將其從您的查詢中刪除,或者您可以設置優先順序,每個address_id只返回1條記錄。

請進一步標記您實際使用的RDBM。 MySQL的例子不具有窗口功能還你標記它尚未使用引用OVER(分區....這將不能在MySQL中可能

;WITH cte (
    SELECT DISTINCT address.address_id, address.address1, address.streetcity, state.stateabbrev, rtrim(ltrim(case when address.streetzipcode is not null and address.streetzipcode != 'NULL' then address.streetzipcode else '' end))+case when len(address.streetzipplus4)>0 then '-'+rtrim(ltrim(address.streetzipplus4)) else '' end as streetzipcode, address.homephone, 
      dbo.f_addressstudent (student.address_id) as Students, 
      dbo.f_addresspeople (student.address_id) as Adults, 
      case 
      when @classif_id IS NULL then 0 
      else 
      student.classif_id 
      end classif, 
      classifctn, 

      ROW_NUMBER() OVER (PARTITION BY address.address_id ORDER BY HOW WILL YOU CHOOSE?) AS RowNum 

     FROM district WITH(NOLOCK) 
      JOIN dbo.building ON building.district_id = district.district_id 
      JOIN dbo.studbldg_bridge WITH(NOLOCK) ON studbldg_bridge.bldg_id=building.bldg_id 
      JOIN dbo.student WITH(NOLOCK) ON student.student_id = studbldg_bridge.student_id 
      JOIN classif with(nolock) on student.classif_id = classif.classif_id 
      LEFT JOIN dbo.address WITH(NOLOCK) ON student.address_id = address.address_id 
      LEFT JOIN dbo.state WITH(NOLOCK) ON address.streetstate_id = state.state_id 
      LEFT JOIN dbo.state AS mailstate WITH(NOLOCK) ON address.state_id = mailstate.state_id 
     WHERE district.district_id = (SELECT district_id FROM dbo.building WITH(NOLOCK) WHERE bldg_id = @bldg_id) 
) 

SELECT * 
FROM 
    cte 
WHERE 
    RowNum = 1 
ORDER BY 
    classif 
    ,Adults 
    ,Students 

另外,您可以嵌套的選擇查詢。說明雖然這種解決方案有點無用,因爲如果你真的不關心色譜柱,那麼只會返回1級/ classifctn,如果你真的不關心色譜柱,那麼你應該從查詢中刪除它。

實際上,你的classifctn和classif列當一個以上的學生在同一個地址時,會導致你多行,這是一種將這些值連接到單行的方法,你應該花更多的時間在你的商業案例上併爲我們定義它。但這裏是一個例子給你:

SELECT DISTINCT 
    address.address_id 
    ,address.address1 
    ,address.streetcity 
    ,state.stateabbrev 
    ,LTRIM(RTRIM(ISNULL(NULLIF(address.streetzipcode,'NULL'),''))) 
     + CASE WHEN LEN(address.streetzipplus4) > 0 THEN '-' ELSE '' END 
     + LTRIM(RTRIM(ISNULL(address.streetzipplus4,''))) AS streetzipcode 
    ,address.homephone 
    ,dbo.f_addressstudent (student.address_id) as Students 
    ,dbo.f_addresspeople (student.address_id) as Adults 
    , case 
     when @classif_id IS NULL then 0 
     else student.classif_id 
     end classif 

     ,STUFF(
     (SELECT ',' + CAST(classif_id AS VARCHAR(100)) 
     FROM 
      classif c 
     WHERE c.classif = student.classif 
     FOR XML PATH('')) 
     ,1,1,'') AS classifs 

     ,STUFF(
     (SELECT ',' + CAST(classifctn AS VARCHAR(100)) 
     FROM 
      classif c 
     WHERE c.classif = student.classif 
     FOR XML PATH('')) 
     ,1,1,'') AS classifctns 
FROM 
    district WITH(NOLOCK) 
    INNER JOIN dbo.building 
    ON building.district_id = district.district_id 
    AND building.bldg_id = @bldg_id 
    INNER JOIN dbo.student WITH(NOLOCK) 
    ON student.student_id = studbldg_bridge.student_id 
    INNER JOIN dbo.address WITH(NOLOCK) 
    ON student.address_id = address.address_id 
    LEFT JOIN dbo.state WITH(NOLOCK) 
    ON address.streetstate_id = state.state_id 

注意我前面的時候,改變了郵政編碼邏輯爲你展示一些使用ISNULL()NULLIF()是在這樣的情況下很有幫助。我還刪除了3個表格,因爲沒有使用2個表格,並且第三個結果用於子查詢中以連接值。此外地址表改爲一個INNER JOIN因爲如果地址不存在,所有的其他信息變爲空白/沒用....

INNER JOIN dbo.studbldg_bridge WITH(NOLOCK) ON studbldg_bridge.bldg_id=building.bldg_id  
    LEFT JOIN dbo.state AS mailstate WITH(NOLOCK) ON address.state_id = mailstate.state_id 
    INNER JOIN classif with(nolock) on student.classif_id = classif.classif_id 
+0

我在結果集中需要此信息,無法刪除。如何設置優先級? – NKhan

+0

這完全取決於你,你將如何確定哪一個classifctn是你想要的?如果你說你想要兩個,那麼你想要將行連接到單個逗號分隔的字符串?如果前者可以使用row_number()OVER(partition by address_id),然後從cte或嵌套查詢中選擇where = 1。而在後者中,我將使用遞歸cte或帶有子選擇的XML PATH。請注意,您必須標記您使用的確切數據庫,因爲答案會不一樣。 – Matt

+0

其實我嘗試了row_number()OVER(按地址ID排序)。但是,當我在哪裏試圖訪問abc它給我錯誤說「無效列」 – NKhan