MySQL двойное соединение / сводная таблица - PullRequest
0 голосов
/ 18 мая 2018

Вот SQL Fiddle


У меня есть таблица, инвентарь , в которой есть некоторые данные, которые выглядят так:

 +--------------+---------+---------------+--------------+------------+------------+
| pmkInventory | fnkPart | inventoryYear | inventoryNum | inventoryR | inventoryC |
+--------------+---------+---------------+--------------+------------+------------+
|            1 |      51 |          2016 |            6 | A          |          4 |
|            2 |    2075 |          2016 |           40 | C          |          4 |
|            3 |      50 |          2016 |            3 | A          |          8 |
|            4 |       3 |          2016 |          600 | F          |          3 |
|            5 |       3 |          2017 |          650 | F          |          3 |
|            6 |     100 |          2016 |            2 | B          |          1 |
|            7 |      50 |          2017 |            5 | A          |          8 |
|            8 |      51 |          2017 |           16 | A          |          4 |
+--------------+---------+---------------+--------------+------------+------------+

Он содержит информацию о количестве и местоположении для каждой части, каждый год.Будет более 2 лет (не только 2016 и 2017), но мне нужно отображать только два года за раз.

Мне нужно придумать оператор SQL, чтобы получить что-то вроде этого:

+---------+---------------+--------------+------------+------------+---------------+--------------+------------+------------+
| fnkPart | inventoryYear | inventoryNum | inventoryR | inventoryC | inventoryYear | inventoryNum | inventoryR | inventoryC |
+---------+---------------+--------------+------------+------------+---------------+--------------+------------+------------+
|      51 | 2016          | 6            | A          | 4          | 2017          | 16           | A          | 4          |
|    2075 | 2016          | 40           | C          | 4          | NULL          | NULL         | NULL       | NULL       |
|      50 | 2016          | 3            | A          | 8          | 2017          | 5            | A          | 8          |
|       3 | 2016          | 600          | F          | 3          | 2017          | 650          | F          | 3          |
|     100 | 2016          | 2            | B          | 1          | NULL          | NULL         | NULL       | NULL       |
|      40 | NULL          | NULL         | NULL       | NULL       | NULL          | NULL         | NULL       | NULL       |
|     504 | NULL          | NULL         | NULL       | NULL       | NULL          | NULL         | NULL       | NULL       |
+---------+---------------+--------------+------------+------------+---------------+--------------+------------+------------+

Из моего чтения звучит так, будто мне нужна какая-то сводная таблица, а поскольку в MySQL нет встроенной таблицы, мне нужно будет использовать операторы CASE. Этот вопрос говорит о сводных таблицах, но я запутался, как использовать его без использования функции count.Мне не нужно ничего подсчитывать, поскольку у меня уже есть данные, хранящиеся в базе данных - мне просто нужно отобразить их.


Решение без сводной таблицы, которое я придумал, вроде работ.Он правильно показывает годы, но не показывает строки с нулевыми значениями.У меня есть таблица деталей с тысячами деталей.Я присоединяюсь к инвентарному столу.Я думал, что, выполнив LEFT JOIN, я получу все детали, даже если в таблице инвентаризации не было данных за указанные годы.

Вот что:

SELECT p.pmkPart, p.partNumber, 
       i1.fnkPart, i1.inventoryYear, i1.inventoryNum, i1.inventoryR, i1.inventoryC, 
       i2.fnkPart, i2.inventoryYear, i2.inventoryNum, i2.inventoryR, i2.inventoryC
FROM part AS p
LEFT JOIN inventory as i1
       ON p.pmkPart = i1.fnkPart
LEFT JOIN inventory as i2
       ON p.pmkPart = i2.fnkPart
WHERE i1.inventoryYear = 2016
AND i2.inventoryYear = 2017
GROUP BY p.pmkPart

Этот запрос даст мне что-то вроде этого.Обратите внимание, что в нем отсутствуют детали 2075 и 100, поскольку они не являются значениями для года 2017. Также исключаются остальные детали из таблицы part, которые не имеют значений в таблице inventory.

+---------+------------+---------+---------------+--------------+------------+------------+---------+---------------+--------------+------------+------------+
| pmkPart | partNumber | fnkPart | inventoryYear | inventoryNum | inventoryR | inventoryC | fnkPart | inventoryYear | inventoryNum | inventoryR | inventoryC |
+---------+------------+---------+---------------+--------------+------------+------------+---------+---------------+--------------+------------+------------+
|      51 | AB-l34     |      51 |          2016 |            6 | A          |          4 |      51 |          2017 |           16 | A          |          4 |
|      50 | AB-l36     |      50 |          2016 |            3 | A          |          8 |      50 |          2017 |            5 | A          |          8 |
|       3 | C-5-BT     |       3 |          2016 |          600 | F          |          3 |       3 |          2017 |          650 | F          |          3 |
+---------+------------+---------+---------------+--------------+------------+------------+---------+---------------+--------------+------------+------------+

У кого-нибудь есть какие-либо предложения о том, как я могу изменить свой существующий запрос, чтобы получить правильный результат?Или как создать сводную таблицу, которая выполняет то, что я хочу?

Годы, которые я выбираю, нужно изменить, но я буду выбирать только два одновременно, 2016 и 2017 или 2016и 2018, или 2017 и 2018, и т. д.

Я понял, как это сделать, используя комбинацию php и MySQL, но я перехожу на новую платформу, где сценарии на стороне серверане вариант, поэтому нужно перенести все в SQL

1 Ответ

0 голосов
/ 18 мая 2018

Попробуйте добавить условие года к самому объединению:

SELECT p.pmkPart, p.partNumber, 
       i1.fnkPart, i1.inventoryYear, i1.inventoryNum, i1.inventoryR, i1.inventoryC, 
       i2.fnkPart, i2.inventoryYear, i2.inventoryNum, i2.inventoryR, i2.inventoryC
FROM part AS p
LEFT JOIN inventory as i1
       ON p.pmkPart = i1.fnkPart
       AND i1.inventoryYear = 2016
LEFT JOIN inventory as i2
       ON p.pmkPart = i2.fnkPart
       AND i2.inventoryYear = 2017

Кроме того, в этом запросе нет агрегатов, поэтому вам не нужно группировать по чему-либо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...