我有一个查询(从存储过程中执行)看起来像这样:
SELECT S.name
INTO #TempA
from tbl_Student S
INNER JOIN tbl_StudentHSHistory TSHSH on TSHSH.STUD_PK=S.STUD_PK
INNER JOIN tbl_CODETAILS C
on C.CODE_DETL_PK=S.GID
WHERE TSHSH.Begin_date < @BegDate
这是问题,第二个内连接和相应的where语句只有在只有某个变量(@UseArchive
)为真时才会发生,如果它是假的,我不希望它发生。此外,在TSHSH
中,某些行可能在S
中没有相应的条目。我尝试将它拆分为基于@UseArchive
的2个单独的查询,但是工作室拒绝编译,因为INTO #TempA
语句说数据库中已经有一个名为#TempA
的对象。任何人都可以告诉我修复查询的方法或使用INTO #TempA
语句拆分查询的方法吗?
答案 0 :(得分:2)
看起来你在这里问了两个问题。
1-如何解决SELECT INTO问题:
SELECT INTO仅在目标表不存在时有效。如果表已经存在,则需要使用INSERT INTO ... SELECT。
2-条件加入:
如果相应的行可能不存在,则需要执行LEFT JOIN。试试这个。
SELECT S.name
FROM tbl_Student S
INNER JOIN tbl_StudentHSHistory TSHSH
ON TSHSH.STUD_PK=S.STUD_PK
LEFT JOIN tbl_CODETAILS C
ON C.CODE_DETL_PK=S.GID
WHERE TSHSH.Begin_date < @BegDate
AND CASE WHEN @UseArchive = 1 THEN c.CODE_DETL_PK ELSE 0 END =
CASE WHEN @UseArchive = 1 THEN S.GID ELSE 0 END
将CASE语句放在WHERE子句而不是JOIN子句中会强制它在@UseArchive时表现为INNER JOIN,而在@UseArchive时则表示LEFT JOIN。
答案 1 :(得分:0)
我用LEFT JOIN替换它
LEFT JOIN tbl_CODETAILS C ON @UseArchive = 1 AND C.CODE_DETL_PK = S.GID
答案 2 :(得分:0)
SELECT S.name
INTO #TempA
from tbl_Student S
INNER JOIN tbl_StudentHSHistory TSHSH
on TSHSH.STUD_PK = S.STUD_PK
INNER JOIN tbl_CODETAILS C
on C.CODE_DETL_PK = S.GID
and @UseArchive = true
WHERE TSHSH.Begin_date < @BegDate
但是在这种情况下将@UseArchive = true放在连接中与其中的方法相同 你的问题对我来说没什么意义 那么如果TSHSH某些行可能在S中没有相应的条目呢?
如果您只希望其中一个联接匹配
SELECT S.name
INTO #TempA
from tbl_Student S
LEFT OUTER JOIN tbl_StudentHSHistory TSHSH
on TSHSH.STUD_PK = S.STUD_PK
LEFT OUTER JJOIN tbl_CODETAILS C
on C.CODE_DETL_PK = S.GID
and @UseArchive = true
WHERE TSHSH.Begin_date < @BegDate
and ( TSHSH.STUD_PK is not null or C.CODE_DETL_PK id not null )
答案 3 :(得分:0)
您可以拆分查询,然后轻松插入临时表。
SELECT * INTO #TempA FROM
(
SELECT * FROM Q1
UNION ALL
SELECT * FROM Q2
) T