2014-10-01 3 views
1

У меня есть сценарий, в котором я работаю над SQL Server Reporting Services для создания табуляционного отчета и застревает в точке, где я получаю повторяющиеся значения для одного столбца. Ниже приведен пример вывода из кода:Обработка нулевых значений и дубликатов записей в SQL Server

AppID EmpID EmpName 
2002912 81555 NULL 
2002912 81588 Jenn - 81588 
2026880 9328 NULL 
2026880 9628 Brad - 09628 
2027065 92174 Julie - 92174 
2027065 92714 NULL 
2028989 72138 NULL 
2028989 91366 Alan - 91366 
2029233 17438 NULL 
2029233 53712 Brad - 53712 
2031585 37902 NULL 
2031588 17723 Richard - 17723 
2031591 54551 Paula - 54551 
2031593 52240 Sarah - 52240 
2031597 72778 Daisy - 72778 
2031603 12659 NULL 

Обратите внимание на первый coulmn (AppID) имеет несколько дубликатов и соответствующий столбец EmpName либо Null или имеет какое-то значение. Я хочу устранить все дубликаты AppID's, где EmpName - null.

Это могло быть прямо, если не было нулевых значений для уникальных AppID (см. Последнюю строку), также я не могу жестко кодировать, поскольку имею дело с большим количеством данных.

Также обратите внимание, что все эти три столбца поступают из разных таблиц и были LEFT JOIN - AppID стол. Пожалуйста, дайте мне знать, если вам нужно увидеть код, я не вставлял его здесь, так как он немного сложный и, возможно, не требуется.

Любой вид помощи и внушения appreciated.Thank вы

+0

Используйте 'ROW_NUMBER OVER (раздел по APPID ORDER BY EmpName NULLS FIRST)' и выберите строку 2.I'm не уверен в синтаксисе, но это общая идея.OR использовать 'ORDER BY (CASE КОГДА EmpNAme NULL THEN 0 ELSE 1 END)', если NULLS FIRST недоступно. – Mihai

+0

Я не хочу исключать значения «нуль», где «AppID» уникален. Таким образом, в этом случае, как это будет отличаться между повторяющимися «AppID» и «Уникальными» AppID'ами? –

ответ

4

Используйте функцию row_number в КТР, а затем выбрать первую строку. Хотя, если есть более одного EmpName, которое не является NULL, вы получите только первый в алфавитном порядке.

WITH AppAndEmp AS 
(
    SELECT 
     AppID 
     , EmpID 
     , EmpName 
     , ROW_NUMBER() OVER(PARTITION BY AppId 
         ORDER BY (CASE WHEN EmpName IS NULL THEN 0 ELSE 1 END) DESC 
           , EmpName) AS EmpOrder 

    FROM 
     dbo.App 
     LEFT JOIN dbo.Emp 
      ON App.AppId = Emp.AppId 
) 

SELECT 
    * 

FROM 
    AppAndEmp 

WHERE 
    EmpOrder = 1 
+0

+1 хороший, добавили его в мой образец sqlfiddle: http://sqlfiddle.com/#!3/67cf0/3/0 – Jakob

+0

Ваш ответ превосходный, и он действительно работает. Я знаю, что мы не должны комментировать, просто говоря спасибо, но я действительно не мог остановить себя, потому что это спасло мне много времени, чтобы получить ответ на это. –

1

EDIT

@djphatic: Благодаря ваш комментарий. Я исправил свой ответ.

-- These are those who have set a EmpName but have an invalid row too 
select * from data where AppID in (
    select AppID from data group by AppID having count(AppID) > 1 
) 
and empname is not null 
union 
-- These are those who MIGHT have set a EmpName or NULL 
select * from data where AppID in (
    select AppID from data group by AppID having count(AppID) = 1 
) 

=>SQLFiddle


Для ради отказа я оставляю мою предыдущуюнеправильныйответ здесь:

Вы могли бы попробовать это один:

select AppID, min(empid) EmpID, min(EmpName) EmpName 
from data 
group by AppID 

SQLFiddle: http://sqlfiddle.com/#!3/67cf0/1/0

MIN игнорирует нулевые значения.

Docs для MIN в SQL Server: http://msdn.microsoft.com/en-us/library/ms179916.aspx

+0

Это даст вам непоследовательные результаты. Используя пример данных для AppId 2026880, вы получите 9328 для EmpId и Brad - 09628 для EmpName. – mheptinstall

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