SQL Server 2000 - выбор одной строки из многих на основе значения ячейки - PullRequest
0 голосов
/ 02 декабря 2011

У меня есть интересная дилемма, которая поставила меня в тупик и коллегу. Я пытаюсь создать SQL-запрос, который позволит мне вытащить телефонные номера сотрудника для публикации на общедоступном веб-сайте. В нашей телефонной системе (на основе SQL Server 2000) пользователь может иметь до трех добавочных номеров (пока): номер 3XXX (прямая линия), 5XXX (группы начальников, для человека с секретарем и многолинейными телефонами) и 7XXX (голосовая почта).

Большинство людей имеют расширение 3XXX или 7XXX. Лишь немногие имеют 5XXX, но у нас также есть люди, которые благодаря акциям получили дополнительные номера. Например, учитель (который получает только голосовую почту / 7XXX) был повышен до принципала помощника и получает прямую линию / 3XXX, а затем становится директором и получает секретаря, таким образом 5XXX.

Мы хотим опубликовать эти числа в порядке 5XXX, затем 3XXX, а затем 7XXX, поэтому большинство прямых маршрутов, использующих ORDER BY, находятся вне окна. Я получил запрос до такой степени, что он вернет что-то вроде этого:

UserID | Extension |Employee ID 
-------------------------------
USER 1 | 3234      |1234
USER 1 | 5235      |1234
USER 1 | 7364      |1234

Однако я не могу полагаться на порядок, в котором они могут быть, в связи с тем, когда их расширение было добавлено в систему. У меня также нет контроля над удалением других расширений.

Мы попытались сделать несколько заявлений по делу, но ничего хорошего не натолкнулись. Ниже приведен SQL, который мы используем, который становится очень сложным и стоит над моей головой. Может ли кто-нибудь пролить свет на то, как мы можем разумно получить одно значение в каждой строке, которое будет возвращать идентификатор сотрудника и добавочный номер телефона в соответствии с приведенными выше правилами? Имя, фамилия просто для проверки и не являются частью финала.

Извините, если это звучит как много, просто отчаянно здесь.

SELECT DISTINCT 
FirstName, LastName, PrimaryFaxNumber, MAX(CASE WHEN Expr1 IS NOT NULL THEN Expr1 ELSE CASE WHEN Expr2 IS NOT NULL 
                      THEN Expr2 ELSE Expr3 END END) AS Extension
FROM         (SELECT     sub.FirstName, sub.LastName, sub.PrimaryFaxNumber, da.DtmfAccessId, CASE WHEN LEFT(CAST(da.DtmfAccessId AS nvarchar), 1) 
                                              = '5' THEN da.DtmfAccessId END AS Expr1, CASE WHEN LEFT(CAST(da.DtmfAccessId AS nvarchar), 1) 
                                              = '3' THEN da.DtmfAccessId END AS Expr2, CASE WHEN LEFT(CAST(da.DtmfAccessId AS nvarchar), 1) 
                                              = '7' THEN da.DtmfAccessId END AS Expr3
                       FROM          Subscriber sub FULL OUTER JOIN
                                              DtmfAccessId da ON da.ParentObjectId = sub.SubscriberObjectId
                       WHERE      (sub.SubscriberObjectId IS NOT NULL) AND (sub.PrimaryFaxNumber IS NOT NULL) AND (CAST(da.DtmfAccessId AS BIGINT) < 9999)) 
                      DERIVEDTBL
GROUP BY FirstName, LastName, PrimaryFaxNumber
ORDER BY LastName, FirstName

Ответы [ 2 ]

1 голос
/ 03 декабря 2011

Выберите все 5xxx UNION 3xx, но не 5xxx union 7xxx, но не 5xxx или 3xxx.

Фактический запрос будет выглядеть так:

SELECT DISTINCT EmployeeID, Extension 
    FROM AccessId 
        WHERE LEFT(CAST(Extension AS nvarchar), 1)='5' 
UNION
SELECT DISTINCT EmployeeID, Extension 
    FROM AccessId 
        WHERE LEFT(CAST(Extension AS nvarchar), 1)='3' 
            AND NOT EXIST (
                SELECT EmployeeID FROM AccessId 
                    WHERE LEFT(CAST(Extension AS nvarchar), 1)='5')
UNION
SELECT DISTINCT EmployeeID, Extension 
    FROM AccessId 
            WHERE LEFT(CAST(Extension AS nvarchar), 1)='7' 
                AND NOT EXIST (
                    SELECT EmployeeID FROM AccessId 
                        WHERE LEFT(CAST(Extension AS nvarchar), 1)='3' 
                            OR LEFT(CAST(Extension AS nvarchar), 1)='5');

Возможно, существуют более быстрые решения.

0 голосов
/ 03 декабря 2011

Если я вас правильно понял, все, что вам нужно, это отсортировать результат по LEFT(extension,1), чтобы у вас было

SELECT * FROM (your_your_query)a
ORDER BY a.user_id, CASE LEFT(a.extension,1)
WHEN '5' THEN 1
WHEN '3' THEN 2
WHEN '7' THEN 3
ELSE 4
END
...