Сравните три значения столбца с тремя входами по размеру в postgres - PullRequest
0 голосов
/ 19 марта 2020

Я пишу программное обеспечение, в котором у меня есть размер ящика (ширина = 10, высота = 20, длина = 10) и база данных Postgres с полками (также определенными по ширине, высоте, длине). Теперь я хочу найти все полки, в которые можно поместить поле c (размеры полки должны быть больше или равны размеру коробки). Первоначально я думал, что смогу сделать это:

SELECT shelves.* WHERE shelves.width = 10 AND shelves.height = 20 AND shelves.length = 10

Тем не менее, моя коробка может поместиться на любой из этих полок, потому что ее можно просто повернуть, чтобы установить:

|------|---------|----------|----------|
|  id  |  width  |  height  |  length  | 
|------|---------|----------|----------|
|  1   |   20    |    10    |    10    |
|------|---------|----------|----------|
|  2   |   10    |    20    |    10    |
|------|---------|----------|----------|
|  2   |   10    |    10    |    20    |
|------|---------|----------|----------|

Так в JavaScript этот код будет выглядеть следующим образом:

const boxdim = [box.width, box.height, box.length].sort();
const shelfdim = [shelf.width, shelf.height, shelf.length].sort();
const canFit = boxdim[0] <= shelfdim[0] && boxdim[1] <= shelfdim[1] && boxdim[2] <= shelfdim[2];

Возможно ли сделать это в Postgres? Мне нужно что-то похожее на это (явно псевдокод и не работает:

SELECT shelves.* WHERE SORT(shelves.width, shelves.height, shelves.length)[0] = 10 AND SORT(shelves.width, shelves.height, shelves.length)[1] = 10 AND SORT(shelves.width, shelves.height, shelves.length)[2] = 20

Любые советы приветствуются.

Ответы [ 2 ]

1 голос
/ 19 марта 2020

Расширение intarray предоставляет функцию sort для массивов, но вы также можете написать ее самостоятельно , если вы не хотите использовать это или иметь другой элемент type.

Теперь, когда in Postgres " Операторы упорядочения массива (<, >=, et c) сравнивают элемент содержимого массива -by-element," Чтобы проверить, меньше ли каждое значение, чем соответствующий размер полки, вы можете использовать UNNEST:

SELECT *
FROM shelves
WHERE (SELECT bool_and(box_dim <= shelf_dim)
       FROM UNNEST(
         sort(ARRAY[width, height, length]),
         ARRAY[10, 10, 20]
       ) AS dims(box_dim, shelf_dim));
1 голос
/ 19 марта 2020

Я не говорю, что вы должны это делать, но в PostgreSQL вы можете делать довольно крутые (или плохие, в зависимости от вашей точки зрения) вещи с массивами:

SELECT id, array_agg(d) FROM (
    SELECT id, unnest(ARRAY[width, height, length]) AS d 
      FROM shelves 
     ORDER BY id, d) X 
 GRUOP BY id;

И вы ваши размеры отсортированы в хороший массив, а ля Javascript. Я предлагаю использовать этот запрос для генерации представления.

Теперь, в зависимости от вашего кода, вы можете сделать это снова с таблицей блоков или просто передать три параметра в правильном порядке в запрос, который будет работать на view.

Я действительно надеюсь, что кто-то предоставит ответ, который использует стандарт SQL, без массивов. В таком случае, пожалуйста, выберите ответ. :)

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