ВЫБЕРИТЕ значение, даже если NULL при левом присоединении - PullRequest
0 голосов
/ 30 апреля 2018

Я пытаюсь извлечь данные и поместить их в отчет 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 голосов
/ 30 апреля 2018

Поскольку два подзапроса в значительной степени идентичны, за исключением оператора 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
0 голосов
/ 30 апреля 2018

Вероятно, не лучший подход, но я получил правильный вывод, используя:

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

0 голосов
/ 30 апреля 2018
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 для выбранной строки, даже если у нее есть нулевые значения.,

...