Набор данных на основе условий SQL

#sql

#sql

Вопрос:

У меня есть база данных SQL Server, которую я не проектировал. У сотрудников есть степени, лицензии и учетные данные, хранящиеся в нескольких разных таблицах. Я написал запрос, чтобы объединить всю эту информацию вместе, чтобы я мог видеть общий результат того, как выглядят данные. Меня попросили создать представление для этих данных, которое возвращает только самую высокую степень, которую они получили, и два самых высоких сертификата. Проблема в том, что, поскольку это уже существующие данные, в данные не встроена иерархия. Все степени и сертификаты просто хранятся в виде строки, связанной с их номером сотрудника. Первым логическим шагом было создание списка смежности (я считаю, что это правильный термин). Например, ‘MD’ — это наивысшая степень, которую вы можете получить в нашем списке. Итак, я присвоил этому «ранжированию» значение 1. Следующая более низкая степень «оценивается» как 2. и так далее. Я могу присоединиться к текстовому полю, которое содержит эти данные, и вернуть их соответствующий ранг. Проблема, с которой я сталкиваюсь, заключается в возврате только двух самых высоких значений на основе этого рейтинга. Если сотрудник имеет несколько степеней или сертификатов, они перечислены во второй или третьей строке. С логической точки зрения мне нужно сгруппировать идентификатор сотрудника, имя и фамилию. Затем, как объединить степени, сертификаты и лицензии на основе «рейтинга», который я создал для них. Это не настоящая иерархия в том смысле, в каком я об этом думаю, потому что мне нужно знать только два самых высоких и не обязательно взаимосвязь между результатами.

Другим потенциальным предостережением является то, что база данных должна оставаться в режиме совместимости с SQL Server 2000.

Любая помощь, которая может быть предоставлена, была бы высоко оценена. Спасибо.

 select a.EduRank as 'Licensure Rank',
   b.EduRank as 'Degree Rank',
   EmpComp.EecEmpNo, 
  EmpPers.EepNameFirst, 
   EmpPers.EepNameLast, 
   RTRIM(EmpEduc.EfeLevel),
   RTRIM(EmpLicns.ElcLicenseID),
   a.EduType,
   b.EduType
       from empcomp 
      join EmpPers on empcomp.eeceeid = EmpPers.eepEEID
      join EmpEduc on empcomp.Eeceeid = EmpEduc.EfeEEID
      join EmpLicns on empcomp.eeceeid = EmpLicns.ElcEEID
      join yvDegreeRanks a on a.EduCode = EmpLicns.ElcLicenseID
      join yvDegreeRanks b on b.EduCode = EmpEduc.EfeLevel
  

Комментарии:

1. Я пытался использовать TOP 2, но мне нужно было бы вернуть TOP 2 для каждого сотрудника, а не для всего набора данных.

Ответ №1:

Думаю, я понимаю, в чем ваша проблема, однако я не уверен. Объединение таблиц вместе дало вам «двойные строки». «Быстрым и грязным» способом решения этого запроса было бы использовать подзапросы, отличные от Joins. При этом вы можете выбрать только TOP 1 степень и TOP 2 сертификаты.

РЕДАКТИРОВАТЬ : Можете ли вы попробовать этот запрос?

 SELECT *
FROM employSELECT tblLicensures.EduRank as 'Licensure Rank',
    tblDegrees.EduRank as 'Degree Rank',
    EmpComp.EecEmpNo, 
    EmpPers.EepNameFirst, 
    EmpPers.EepNameLast, 
    RTRIM(tblDegrees.EfeLevel),
    RTRIM(tblLicensures.ElcLicenseID),
    tblLicensures.EduType,
    tblDegrees.EduType
FROM EmpComp
    LEFT OUTER JOIN EmpPers ON empcom.eeceeid = EmpPers.eepEEID
    LEFT OUTER JOIN
        -- Select TOP 2 Licensure Ranks
        (
            SELECT TOP 2 a.EduType, a.EduRank, EmpLicns.ElcEEID
            FROM yvDegreeRanks a 
                INNER JOIN EmpLicns on a.EduCode = EmpLicns.ElcLicenseID
            WHERE EmpLincs.ElcEEID = empcomp.eeceeid
            ORDER BY a.EduRank ASC
        ) AS tblLicensures ON tblLicensures.ElcEEID = empcomp.Eeceeid
    LEFT OUTER JOIN 
        -- SELECT TOP 1 Degree
        (
            SELECT TOP 1 b.EduType, b.EduRank, EmpEduc.EfeEEID, EmpEduc.EfeLevel
            FROM yvDegreeRanks b 
                INNER JOIN EmpEduc on b.EduCode = EmpEduc.EfeLevel
            WHERE EmpEduc.EfeEEID = empcomp.Eeceeid
            ORDER BY b.EduRank ASC
        ) AS tblDegrees ON tblDegrees.EfeEEID = empcomp.Eeceeid  

Комментарии:

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

2. Хорошо, я сейчас пойду домой с работы и посмотрю на это, когда буду там. К тому времени это может быть решено, если нет, я немного поработаю над этим 🙂

3. @Mike: можете ли вы попробовать запрос, который я только что опубликовал?

Ответ №2:

Это не самое элегантное решение, но, надеюсь, оно хотя бы каким-то образом поможет вам.

 create table #dataset (
licensurerank [datatype],
degreerank [datatype],
employeeid [datatype],
firstname varchar,
lastname varchar,
efeLevel  [datatype],
elclicenseid [datatype],
edutype1 [datatype],
edutype2 [datatype]
)

select distinct identity(int,1,1) [ID], EecEmpNo into #employeeList from EmpComp

declare
    @count int,
    @rows int,
    @employeeNo int

select * from #employeeList
set @rows = @@rowcount
set @count = 1

while @count <= @ROWS
    begin

select @employeeNo = EecEmpNo from #employeeList where id = @count

        insert into #dataset
        select top 2 a.EduRank as 'Licensure Rank',
           b.EduRank as 'Degree Rank',
           EmpComp.EecEmpNo, 
          EmpPers.EepNameFirst, 
           EmpPers.EepNameLast, 
           RTRIM(EmpEduc.EfeLevel),
           RTRIM(EmpLicns.ElcLicenseID),
           a.EduType,
           b.EduType
               from empcomp 
              join EmpPers on empcomp.eeceeid = EmpPers.eepEEID
              join EmpEduc on empcomp.Eeceeid = EmpEduc.EfeEEID
              join EmpLicns on empcomp.eeceeid = EmpLicns.ElcEEID
              join yvDegreeRanks a on a.EduCode = EmpLicns.ElcLicenseID
              join yvDegreeRanks b on b.EduCode = EmpEduc.EfeLevel
            where EmpComp.EecEmpNo = @employeeNo

    set @count = @count   1
end
  

Ответ №3:

Создайте таблицы для сотрудников, типов степеней (включая ранг), типов сертификатов (включая ранг) и объедините таблицы employees_degrees и employees_certs. [Возможно, было бы лучше поместить степени и сертификаты в одну таблицу с флагом is_degree, если все остальные их поля одинаковы.] Вы можете извлечь существующие строковые значения и заменить их идентификаторами FK в таблицах degree и cert.

Сам запрос сложнее, потому что PARTITION BY недоступен в SQL Server 2000 (согласно Google). В ответе UW есть по крайней мере две проблемы: вам нужны LEFT JOIN s, потому что не у всех сотрудников есть степени и сертификаты, и нет ORDER BY того, что вы хотите использовать наилучшим образом из. TOP 2 подзапросы особенно сложны в использовании в этом контексте. Итак, на этот вопрос я пока не могу дать ответ.