问题
I have two tables that I need to join and need to get the data that I can use to plot.
Sample data for two tables are:
**table1**
mon_pjt month planned_hours
pjt1 01-10-2019 24
pjt2 01-01-2020 67
pjt3 01-02-2019 12
**table2**
date project hrs_consumed
07-12-2019 pjt1 7
09-09-2019 pjt2 3
12-10-2019 pjt1 4
01-02-2019 pjt3 5
11-10-2019 pjt1 4
Sample Output, where the actual hours are summation of column hrs_consumed in table2. Following is the sample output:
project label planned_hours actual_hours
pjt1 Oct-19 24 8
pjt1 Dec-19 0 7
pjt2 Sep-19 0 3
pjt2 Jan-20 67 0
pjt3 Feb-19 12 5
I have tried the following query but it gives error:
Select Sum(a.hrs_consumed), a.date, a.planned_hours
From (SELECT t1.date, t2.month, t1.project, t1.hrs_consumed, t2.planned_hours
from table1 t1 JOIN
table2 t2
on t2.month = t1.date
UNION
SELECT t1.date, t2.month, t1.mon_pjt, t2.hrs_consumed, t1.planned_hours
from table t1 JOIN
table2 t2
on t1.date != t2.month
)
I have tried another way also extracting two tables separately and in javascript trying to join it and sort it but that was also vain.
回答1:
In Javascript, you could mimic an SQL like request.
This code takes a pipe and
- selects wanted key and formats
date
into a comparable format, - groups by
date
, - gets the sum of
hrs_consumed
for each group, - makes a full join (with an updated data set for comparable keys/columns),
- selects wanted keys,
- applies a sorting.
const
pipe = (...functions) => input => functions.reduce((acc, fn) => fn(acc), input),
groupBy = key => array => array.reduce((r, o) => {
var fn = typeof key === 'function' ? key : o => o[key],
temp = r.find(([p]) => fn(o) === fn(p));
if (temp) temp.push(o);
else r.push([o]);
return r;
}, []),
sum = key => array => array.reduce((a, b) => ({ ...a, [key]: a[key] + b[key] })),
select = fn => array => array.map(fn),
fullJoin = (b, ...keys) => a => {
const iter = (array, key) => array.forEach(o => {
var k = typeof key === 'function' ? key(o) : o[key];
temp[k] = { ...(temp[k] || {}), ...o };
});
var temp = {};
iter(a, keys[0]);
iter(b, keys[1] || keys[0]);
return Object.values(temp);
},
order = keys => array => array.sort((a, b) => {
var result;
[].concat(keys).some(k => result = a[k] > b[k] || -(a[k] < b[k]));
return result
});
var table1 = [{ mon_pjt: 'pjt1', month: '2019-10', planned_hours: 24 }, { mon_pjt: 'pjt2', month: '2020-01', planned_hours: 67 }, { mon_pjt: 'pjt3', month: '2019-02', planned_hours: 12 }],
table2 = [{ date: '2019-12-07', project: 'pjt1', hrs_consumed: 7 }, { date: '2019-09-09', project: 'pjt2', hrs_consumed: 3 }, { date: '2019-10-12', project: 'pjt1', hrs_consumed: 4 }, { date: '2019-02-01', project: 'pjt3', hrs_consumed: 5 }, { date: '2019-10-11', project: 'pjt1', hrs_consumed: 4 }],
result = pipe(
select(o => ({ ...o, date: o.date.slice(0, 7) })),
groupBy('date'),
select(sum('hrs_consumed')),
fullJoin(
select
(({ mon_pjt: project, month: date, ...o }) => ({ project, date, ...o }))
(table1),
'date'
),
select(({ project, date: label, planned_hours = 0, hrs_consumed = 0 }) => ({ project, label, planned_hours, hrs_consumed })),
order(['project', 'label'])
)(table2);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
回答2:
SELECT project, label,planned_hours,(planned_hours-hours_consumed) AS actual_hours
FROM(
SELECT t1.mon_pjt AS project,date_format(t1.month,'%M-%Y') AS label,
t1.planned_hours,0 AS hours_consumed
FROM table1 t1
UNION
SELECT t2.project,date_format(t2.date,'%M-%Y') AS label,0 as planned_hours,
sum(t2.hours_consumed) AS hours_consumed
FROM table1 t2
GROUP BY project)t
GROUP BY t.project
ORDER BY project
来源:https://stackoverflow.com/questions/60560511/sql-query-to-get-a-joinned-table