SELECT值,即使LEFT JOIN为NULL也是如此

时间:2018-04-30 06:06:02

标签: tsql stimulsoft

我正在尝试将数据拉出来并将其放入Stimulsoft报告中。我遇到的问题是我需要输出到两列。即使分配给所述记录的计数为NULL,我也需要显示每个“管理器”记录。

这就是我现在所拥有的:

DECLARE @ManagerCount INT = (( SELECT Count(*) FROM AM WHERE dbo.AM.AMCurrent = 1 AND dbo.AM.OmitInReport = 0 ) + 1) / 2

DECLARE @tmp_AM1 TABLE (AMID INT, AMName NVARCHAR(100), ID INT)
INSERT INTO @tmp_AM1 SELECT AMID, AMName, row_number() over (order by AMID ) FROM AM
WHERE dbo.AM.AMCurrent = 1 AND dbo.AM.OmitInReport = 0  

SELECT * FROM (
    SELECT ta.id AS id1, ta.AMName AS ManagerName1, COUNT(*) AS ManagerCount1 FROM @tmp_AM1 tA  INNER JOIN Job J ON tA.AMID = j.AMID
    WHERE ta.ID BETWEEN 1 AND @ManagerCount AND j.jobStatusID != 5
    GROUP BY ta.ID, ta.AMName
) a
LEFT JOIN
(
    SELECT ta.id AS id2,ta.AMName AS ManagerName2, COUNT(*) AS ManagerCount2 FROM @tmp_AM1 tA  INNER JOIN Job J ON tA.AMID = j.AMID
    WHERE ta.ID > @ManagerCount AND j.jobStatusID != 5
    GROUP BY ta.AMName, ta.ID
) b ON a.id1 + @ManagerCount = b.id2

最终返回的内容如下:

enter image description here

有18个经理,每列9个,但是这个代码并没有全部显示,因为在第一个左连接中没有计数的任何东西都不显示,因此第2列中的同一行没有不显示。

SELECT * FROM @ tmp_AM1的结果:

enter image description here

3 个答案:

答案 0 :(得分:0)

DECLARE @tmp_AM1 TABLE (AMID INT, AMName NVARCHAR(100), ID INT)
INSERT INTO @tmp_AM1 SELECT AMID, AMName, row_number() over (order by AMID ) FROM AM
WHERE dbo.AM.AMCurrent = 1 AND dbo.AM.OmitInReport = 0  

SELECT * FROM (
    SELECT ta.id AS id1, ta.AMName AS ManagerName1, COUNT(*) AS ManagerCount1 FROM @tmp_AM1 tA  INNER JOIN Job J ON tA.AMID = j.AMID
    WHERE ta.ID BETWEEN 1 AND @ManagerCount AND j.jobStatusID != 5
    GROUP BY ta.ID, ta.AMName
) a
LEFT OUTER JOIN
(
    SELECT ta.id AS id2,ta.AMName AS ManagerName2, COUNT(*) AS ManagerCount2 FROM @tmp_AM1 tA  INNER JOIN Job J ON tA.AMID = j.AMID
    WHERE ta.ID > @ManagerCount AND j.jobStatusID != 5
    GROUP BY ta.AMName, ta.ID
) b ON a.id1 + @ManagerCount = b.id2 where ManagerName2 IS Null and ManagerCount2  IS NULL

只是你想对选择行使用LEFT OUTER JOIN,即使有任何空值。

答案 1 :(得分:0)

由于两个子查询几乎完全相同,除了where语句,我会将其重写为一个查询。我不确定为什么你需要在结果中输入不同列的相同列,但是这样的东西可能有效:

WITH cte AS (
    SELECT 
        ta.id AS id
        ,ta.AMName AS ManagerName
        ,COUNT(*) AS ManagerCount
        ,CASE WHEN ta.ID BETWEEN 1 AND @ManagerCount THEN 0 ELSE 1 END AS something
    FROM 
        @tmp_AM1 tA  
        INNER JOIN Job J ON tA.AMID = j.AMID
    WHERE
        j.jobStatusID != 5
    GROUP BY
        ta.ID
        ,ta.AMName
        ,CASE WHEN ta.ID BETWEEN 1 AND @ManagerCount THEN 0 ELSE 1 END
)
SELECT
    CASE WHEN something = 0 THEN cte.id ELSE null END AS id1
    ,CASE WHEN something = 0 THEN cte.ManagerName ELSE null END AS ManagerName1
    ,CASE WHEN something = 0 THEN cte.ManagerCount ELSE null END AS ManagerCount1
    ,CASE WHEN something = 1 THEN cte.id ELSE null END AS id2
    ,CASE WHEN something = 1 THEN cte.ManagerName ELSE null END AS ManagerName2
    ,CASE WHEN something = 1 THEN cte.ManagerCount ELSE null END AS ManagerCount2
FROM
    cte

答案 2 :(得分:-1)

可能不是最好的方法,但我使用以下方法获得了正确的输出:

DECLARE @ManagerCount INT = (( SELECT Count(*) FROM AM WHERE dbo.AM.AMCurrent = 1 AND dbo.AM.OmitInReport = 0 ) + 1) / 2

DECLARE @tmp_AM1 TABLE (AMID INT, AMName NVARCHAR(100), ID INT)
INSERT INTO @tmp_AM1 SELECT AMID, AMName, row_number() over (order by AMID ) FROM AM
WHERE dbo.AM.AMCurrent = 1 AND dbo.AM.OmitInReport = 0 
ORDER By AMName 

SELECT ManagerName1, ManagerName2, ManagerCount1, ManagerCount2 FROM (
SELECT AMID, ta.id AS id1, ta.AMName AS ManagerName1 FROM @tmp_AM1 tA 
    WHERE (ta.ID BETWEEN 1 AND @ManagerCount)
) a
LEFT JOIN
(
    SELECT AMID, ISNULL(COUNT(*), 0) AS ManagerCount1 FROM Job j
    INNER JOIN tblJobOutcome jO ON j.JobOutcomeID = jo.JobOutcomeID AND jO.JobOutcomeID != 5
    GROUP BY AMID
) a1 ON a.AMID = a1.AMID
LEFT JOIN
(
    SELECT AMID, ta.id AS id2, ta.AMName AS ManagerName2 FROM @tmp_AM1 tA 
    WHERE (ta.ID > @ManagerCount)
) b ON a.id1 + @ManagerCount = b.id2
LEFT JOIN
(
    SELECT AMID, ISNULL(COUNT(*), 0) AS ManagerCount2 FROM Job j 
    INNER JOIN tblJobOutcome jO ON j.JobOutcomeID = jo.JobOutcomeID AND jO.JobOutcomeID != 5
    GROUP BY AMID
) b1 ON b.AMID = b1.AMID

在两列中给出正确的输出。

给了我这个:

enter image description here