SQL查询连接条件

时间:2013-04-30 20:22:37

标签: sql sql-server tsql

我有一个查询(从存储过程中执行)看起来像这样:

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语句拆分查询的方法吗?

4 个答案:

答案 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