我无法通过搜索找到它,所以我想我问的不是正确的方法,因此欢迎您提供帮助。
我们有一个查询表:
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语句中的select替换为:
When StatusId = 1 THEN @LookUp
When StatusId = 2 THEN @LookUp2
该视图遍历数百万条记录,并且从查找表中为每一行进行选择的过程确实很慢。
答案 0 :(得分:3)
为什么不简单地使用联接?
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.上观看实时演示
答案 1 :(得分:0)
创建一个SQL函数,该函数根据ID返回Name。
Create FUNCTION [dbo].[GetLookUpValue]
(
@Id int
)
RETURNS varchar(500)
AS BEGIN
return(Select Name from LOOKUP_table with(nolock) where Id=@Id)
END