2016-08-08 2 views
1

Мне нужно получить только отдельный адрес_ид, в результате не будет дублирования. Вот мой запрос.Удалить дубликат address_id из набора данных sql

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 (partition by address.address_id), но он также не работал.

Любая помощь будет оценена заранее.

Спасибо

** UPDATE на бизнес-логики/Требования **

Мне нужно, чтобы получить уникальные адреса для родителей студентов. Поскольку у родителя могут быть два или более детей, живущих по одному адресу, это вызывает дублирование. Другими словами, мне нужно получить только одного ребенка на одного родителя.

+1

Когда есть дубликаты, как следует классификация (например) определяется? Не полностью определяя ваши требования, невозможно получить «правильный» ответ. –

+0

Я удалил тег mysql, потому что, если вы пытаетесь использовать функцию OVER (раздел ...), это означает, что вы не используете ее, поскольку функции окна не существуют в mysql. Пожалуйста, отметьте только те rdbms, которые вы используете. – Matt

+0

Я обновляю вопрос, чтобы предоставить вам больше информации о требованиях. – NKhan

ответ

0

С вашего изображения результатов это выглядит так, что столбец classifctn имеет более 1 значения, поэтому он повторяет вашу строку. Чтобы получить 1 отдельный адрес_ид и остальные столбцы, либо удалите его из вашего запроса, либо вы можете установить приоритет, который будет возвращать только 1 запись на адрес address_id

далее, пожалуйста, отметьте только те РСУБ, которые вы используете на самом деле. 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, если в домохозяйстве существует более 1, если вы действительно не заботитесь о столбце, тогда вы должны просто удалить его из своего запроса.

Фактически оба столбца 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 

Примечание I, когда вперед и изменил код логики зип, чтобы показать вам некоторые использования ISNULL() и NULLIF(), которые являются полезными в подобных случаях. Я также удалил 3 таблицы, потому что 2 не используются, а третий заканчивается тем, что используется в подзапросе, чтобы объединить значения. Также адрес таблица была изменена на внутреннее соединение, потому что, если адрес не существует все другой информации становится пустым/бесполезным ....

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

, который полностью зависит от вас, как вы определяете, какой класс является тем, который вам нужен? Если вы говорите, что хотите, то и вы хотите объединить строки в одну разделенную запятыми строку? Если первое вы могли использовать row_number() OVER (partition by address_id), а затем выберите where = 1 из cte или вложенного запроса. И в последнем я бы использовал либо рекурсивный cte, либо XML PATH с подбором select. Обратите внимание, что вы должны пометить точную базу данных, которую используете, поскольку ответы будут изменяться. – Matt

+0

На самом деле я попробовал row_number() OVER (order by address_id). Но когда в where, где я пытался получить доступ к abc, он дает мне ошибку, которая говорит «недопустимый столбец» – NKhan

Смежные вопросы