Формирование сводной таблицы из двух динамических массивов

Имеется таблица Equipments

UUID Название Суммарное количество на складе
1 Название 1 415
2 Название 2 814
3 Название 3 186

и таблица Orders

UUID № Заказа Поставщик Количество в заказе Изделие Прочая информация
1 192921101 Поставщик 1 123 2 etc.
2 101410824 Поставщик 2 61 1 etc.

Необходимо сформировать сводную таблицу по Изделиям/Заказам с расчетом остатков вида:

UUID Название Суммарное количество на складе Поставщик 1 Поставщик 2 Поставщик 3 ... Остаток
1 Название 1 415 - 61 - - 354
2 Название 2 814 123 - - - 691

Необходима реализация либо средствами SQL (Oracle) либо JS.


Ответы (1 шт):

Автор решения: ksa

Необходима реализация либо средствами SQL (Oracle) либо JS.

Предложу такой вариант реализации на JS...

const ot = document.querySelector('table')
const equipments = [
    {
        uuid: 1,
        name: 'Название 1',
        count: 415
    },
    {
        uuid: 2,
        name: 'Название 2',
        count: 814
    },
    {
        uuid: 3,
        name: 'Название 3',
        count: 186
    },
]
const me = new Map(equipments.map(({uuid, name, count}) => [uuid, {name, count}]))
const orders = [
    {
        uuid: 1,
        num: 192921101,
        provider: 'Поставщик 1',
        count: 123,
        equipment: 2,
        bother: 'etc.'
    },
    {
        uuid: 2,
        num: 101410824,
        provider: 'Поставщик 2',
        count: 61,
        equipment: 1,
        bother: 'etc.'
    },
]
const ap = [...new Set(orders.map(o => o.provider))]
const res = [...orders.reduce((m, o) => {
    const e = me.get(o.equipment)
    if (!m.has(e.name)) m.set(e.name, {
        name: e.name, 
        sum: e.count,
        ap: Array(ap.length).fill(0),
        rem: e.count
    })
    const obj = m.get(e.name)
    const i = ap.indexOf(o.provider)
    obj.ap[i] += o.count
    obj.rem -= o.count
    m.set(e.name, obj)
    return m
}, new Map).values()].sort((a, b) => {
    if (a.name === b.name) return 0
    if (a.name > b.name) return 1
    return -1
})
let obj = ot.querySelector('thead th:last-child')
ap.forEach(v => obj.insertAdjacentHTML('beforeBegin', `<th>${v}</th>`))
obj = ot.querySelector('tbody')
res.forEach((o, i) => {
    const or = document.createElement('tr')
    or.insertAdjacentHTML('beforeEnd', `<td>${i + 1}</td>`)
    or.insertAdjacentHTML('beforeEnd', `<td>${o.name}</td>`)
    or.insertAdjacentHTML('beforeEnd', `<td>${o.sum}</td>`)
    o.ap.forEach(v => or.insertAdjacentHTML('beforeEnd', `<td>${v ? v : '-'}</td>`))
    or.insertAdjacentHTML('beforeEnd', `<td>${o.rem}</td>`)
    obj.insertAdjacentElement('beforeEnd', or)
})
<table border='1'>
    <thead>
        <tr>
        <th>UUID</th>
        <th>Название</th>
        <th>На складе</th>
        <th>Остаток</th>
        </tr>
    </thead>
    <tbody></tbody>
</table>

→ Ссылка