Слева объединить две таблицы и сгруппировать по общему идентификатору между двумя и общим идентификатором между всеми тремя - PullRequest
0 голосов
/ 17 сентября 2018

У меня есть три таблицы (две из них на самом деле являются «представлениями»).Я хочу покинуть таблицы 2 и 3 и сгруппировать их по двум общим столбцам, а затем выполнить некоторые подсчеты.Я боролся всю ночь, и я просто собираюсь выбросить свой ноутбук из окна

Вот мои три стола:

+-----------------------+
| Features              |
+-----------------------+
| featureId | title     |
+-----------+-----------+
| feature1  | Feature 1 |
+-----------+-----------+
| feature2  | Feature 2 |
+-----------+-----------+
| feature3  | Feature 2 |
+-----------+-----------+


+--------------------------+--------+
| Tasks                    |        |
+--------------------------+--------+
| featureId | workstreamId | title  |
+-----------+--------------+--------+
| feature1  | workstream1  | Task 1 |
+-----------+--------------+--------+
| feature2  | workstream2  | Task 2 |
+-----------+--------------+--------+
| feature2  | workstream3  | Task 3 |
+-----------+--------------+--------+
| feature2  | workstream3  | Task 3 |
+-----------+--------------+--------+

+--------------------------+-------+
| Jobs                     |       |
+--------------------------+-------+
| featureId | workstreamId | title |
+-----------+--------------+-------+
| feature3  | workstream1  | Job 1 |
+-----------+--------------+-------+
| feature2  | workstream2  | Job 2 |
+-----------+--------------+-------+
| feature2  | workstream3  | Job 3 |
+-----------+--------------+-------+

И вот результат, который я хочуget to:

+-----------+--------------+-----------+----------+
| featureId | workstreamId | taskCount | jobCount |
+-----------+--------------+-----------+----------+
| feature1  | workstream1  | 1         | 0        |
+-----------+--------------+-----------+----------+
| feature2  | workstream2  | 1         | 1        |
+-----------+--------------+-----------+----------+
| feature2  | workstream3  | 2         | 1        |
+-----------+--------------+-----------+----------+
| feature3  | workstream1  | 0         | 1        |
+-----------+--------------+-----------+----------+

Я хочу группировать по featureId и workstreamId - эта комбинация должна быть уникальной в результатах.Я чувствую, что это должно быть действительно легко, но я просто не могу понять.

Вот что у меня есть:

SELECT 
    f.title, 
    t.workstreamId,
    t.taskCount,
    j.jobCount
FROM features f
LEFT JOIN (
        SELECT  
                featureId, 
                workstreamId,
                COUNT(workstreamId) AS taskCount
        FROM tasks
        GROUP BY workstreamId, featureId
    ) AS t
ON t.featureId = f.featureId
LEFT JOIN 
    (
        SELECT  
                featureId,
                workstreamId,
                COUNT(workstreamId) AS jobCount
        FROM jobs
        GROUP BY featureId, workstreamId
    ) AS j
ON j.featureId = f.featureId

Любая помощь приветствуется: -)

Ответы [ 3 ]

0 голосов
/ 17 сентября 2018

FULL JOIN сначала подзапросы, а затем LEFT JOIN результат до features.

SELECT f.featureid,
       coalesce(t.workstreamid, j.workstreamid) workstreamid,
       coalesce(t.count, 0) taskcount,
       coalesce(j.count, 0) jobcount
       FROM features f
            LEFT JOIN ((SELECT featureid,
                               workstreamid,
                               count(*) count
                               FROM tasks
                               GROUP BY featureid,
                                        workstreamid) t
                       FULL JOIN (SELECT featureid,
                                         workstreamid,
                                         count(*) count
                                         FROM jobs
                                         GROUP BY featureid,
                                                  workstreamid) j
                                 ON t.featureid = j.featureid
                                    AND t.workstreamid = j.workstreamid)
                      ON coalesce(t.featureid, j.featureid)  = f.featureid;

db <> fiddle

Это также работает,когда заголовки обнуляются и содержат нули: db <> fiddle

0 голосов
/ 17 сентября 2018

Самый простой способ сделать это - присоединить features к ОБЪЕДИНЕНИЮ таблиц tasks и jobs и выполнить СЧЕТЫ для разных названий. Хитрость в том, что в UNION у нас есть NULL для названия работы из таблицы tasks и NULL для задания из таблицы jobs, что позволяет правильно добавлять счетчики для каждого типа:

SELECT f.featureId, u.workstreamId, COUNT(u.tasktitle) AS taskCount, COUNT(u.jobtitle) AS jobCOunt
FROM features f
JOIN (SELECT featureId, workstreamId, 'Task' AS tasktitle, NULL AS jobtitle
      FROM tasks
      UNION ALL
      SELECT featureId, workstreamId, NULL AS tasktitle, 'Job' AS jobtitle
      FROM jobs) u
ON u.featureId = f.featureId
GROUP BY f.featureId, u.workstreamId
ORDER BY f.featureId

Выход:

featureId   workstreamId    taskCount   jobCOunt
feature1    workstream1     1           0
feature2    workstream2     1           1
feature2    workstream3     2           0
feature3    workstream1     0           1

Демонстрация SQLFiddle

0 голосов
/ 17 сентября 2018

Вам необходимо создать полную таблицу по Tasks и Jobs таблицам.

следующий шаг записывает два подзапроса LEFT JOIN для Tasks и Jobs base на полную таблицу, затем получает count

;WITH CTE AS (
    SELECT distinct t1.featureId,t1.workstreamId
    FROM (
        select featureId,workstreamId from Tasks
        UNION ALL
        select featureId,workstreamId from Jobs
    ) t1 
) 

SELECT t1.featureId,t1.workstreamId,JobsCnt,TasksCnt
FROM 
(
    SELECT t1.featureId,t1.workstreamId,COUNT(t3.title)JobsCnt  
    FROM CTE t1 
    LEFT JOIN Jobs t3 
    on t1.featureId = t3.featureId and t1.workstreamId = t3.workstreamId
    GROUP By t1.featureId,t1.workstreamId
)t1 join 
(
    SELECT t1.featureId,t1.workstreamId,COUNT(t3.title)TasksCnt 
    FROM CTE t1 
    LEFT JOIN Tasks t3 
    on t1.featureId = t3.featureId and t1.workstreamId = t3.workstreamId
    GROUP By t1.featureId,t1.workstreamId
) t2 on t1.featureId = t2.featureId and t1.workstreamId = t2.workstreamId

sqlfiddle

...