T-SQL Получить значения из таблицы поиска и использовать в представлении / хранимой процедуре - PullRequest
1 голос
/ 27 июня 2019

Я не смог найти это с помощью поиска, поэтому, я думаю, я не спрашиваю об этом правильно, поэтому помощь приветствуется.

У нас есть таблица поиска:

Id   Name
------------------
1    "Test"
2    "New"
3    "InProgress"

Таблица 2:

StatusId  SomethingElse
  1   
  2

Таблица 1

ID  Other Other StatusId (Fkey to Table2) ...

Затем у нас есть представление, которое выбирает из нескольких таблиц, и один из столбцов является оператором CASE:

    SELECT * FROM Table1 t1 -- has million records

    CASE When t1.StatusId = 1 THEN (SELECT Name from LOOKUP table where ID = 1) END --'Test'
    CASE When t1.StatusId = 2 THEN (SELECT Name from LOOKUP table where ID = 2) END --'New'
CASE When t3.Date is not null THEN (SELECT Name from LOOKUP table where ID = 3) END --'In Progress'
-- AND ALSO the case look at other tables another 5-6 tables and there are conditions from there
INNER JOIN Table2 t2 on ...
INNER JOIN Table3 t3 on ...

Как видите, это действительно статические значения.

Я хочу загрузить их один раз в переменные, например,

 @LookUp1 = SELECT [NAME] FROM LookUP WHERE Id = 1, 
 @LookUp2 = SELECT [NAME] FROM LookUP WHERE Id = 2 

и заменить выбор в операторе CASE следующим:

When StatusId = 1 THEN @LookUp
When StatusId = 2 THEN @LookUp2

Представление просматривает миллионы записей, и становится очень медленно выполнять выбор из таблицы поиска для каждой строки.

Ответы [ 2 ]

3 голосов
/ 27 июня 2019

Почему бы просто не использовать объединение?

SELECT <columns list from main table>, Lt.Name
FROM <main table> As Mt -- Do not use such aliases in real code!
JOIN <SecondaryTable> As St -- this represents your Table3
    ON <condition> 
[LEFT] JOIN <Lookup table> As Lt
    ON Mt.StatusId = Lt.Id
    OR (Lt.Id = 3 AND St.Date is not null)

Конечно, замените <columns list from main table> на фактический список столбцов, <main table> на имя главной таблицы и т. Д.

Объединение может быть внутренним или левым соединением, в зависимости от обнуляемости столбца StatusId в основной таблице и, если оно допускает обнуляемость, от того, что вы хотите получить в таких случаях (либо строка с нулевым именем, либо без строкина всех).

Я собрал небольшую демонстрацию, чтобы показать вам, что именно я имею в виду.

Создание и заполнение примеров таблиц ( Пожалуйста, сохраните этот шаг вВаши будущие вопросы):

CREATE TABLE LookUp (Id int, Name varchar(10));

INSERT INTO LookUp (Id, Name) VALUES
(1, 'Test'), (2, 'New'), (3, 'InProgress');


CREATE TABLE Table1 (Id int not null, StatusId int null);

INSERT INTO Table1(Id, StatusId)
SELECT n, CASE WHEN n % 3 = 0 THEN NULL ELSE (n % 3) END
FROM
(
    SELECT TOP 30 ROW_NUMBER() OVER(ORDER BY @@SPID) As n
    FROM sys.objects
) tally

CREATE TABLE Table3
(
    Id int not null,
    Date date null
)
INSERT INTO Table3 (Id, Date) 
SELECT Id,  CASE WHEN StatusId IS NULL AND Id % 4 = 0 THEN GetDate() END
FROM Table1

Запрос:

SELECT  Table1.Id, 
        Table1.StatusId, 
        Table3.Date,
        LookUp.Name
FROM Table1
JOIN Table3
    ON Table1.Id = Table3.Id
LEFT JOIN LookUp 
    ON Table1.StatusId = LookUp.Id
    OR (LookUp.Id = 3 AND Table3.Date IS NOT NULL)

Результаты:

Id  StatusId    Date            Name
1   1           NULL            Test
2   2           NULL            New
3   NULL        NULL            NULL
4   1           NULL            Test
5   2           NULL            New
6   NULL        NULL            NULL
7   1           NULL            Test
8   2           NULL            New
9   NULL        NULL            NULL
10  1           NULL            Test
11  2           NULL            New
12  NULL        27.06.2019      InProgress
13  1           NULL            Test
14  2           NULL            New
15  NULL        NULL            NULL
16  1           NULL            Test
17  2           NULL            New
18  NULL        NULL            NULL
19  1           NULL            Test
20  2           NULL            New
21  NULL        NULL            NULL
22  1           NULL            Test
23  2           NULL            New
24  NULL        27.06.2019      InProgress
25  1           NULL            Test
26  2           NULL            New
27  NULL        NULL            NULL
28  1           NULL            Test
29  2           NULL            New
30  NULL        NULL            NULL

Вы также можете увидеть живую демонстрацию на rextester.

0 голосов
/ 27 июня 2019

Создайте функцию SQL, которая возвращает Name в соответствии с Id.

Create FUNCTION [dbo].[GetLookUpValue] 
(
@Id int
)
RETURNS varchar(500)
AS BEGIN
    return(Select Name from LOOKUP_table with(nolock) where Id=@Id)
END
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...