#tsql
#tsql
Вопрос:
У меня есть три связанные таблицы SQL, упрощенные, они выглядят следующим образом:
ShopTable
[ShopID]
ShelfTable
[ShelfID]
[ShopID]
InventoryTable
[ShelfID]
[Value]
[shopId] и [ShelfID] являются отношениями. Теперь то, что я хочу сделать, это получить СУММУ [Value] для одного [shopId], но это, очевидно, не сработает, поскольку [shopId] не является частью InventoryTable:
SELECT SUM([Value]) WHERE [ShopID] = '1'
Как мне написать запрос для фильтрации InventoryTable с использованием shopId?
Комментарии:
1. «[shopId] и [ShelfID] являются отношениями» — это не так. Они используются в качестве первичных / внешних ключей. Во фразе «реляционная база данных» слово «реляционный» происходит из математической теории, и эквивалентом в мире баз данных SQL является таблица (хотя есть места, где SQL не соответствует математической модели)
2. @Damien, ах, извините за неправильное использование терминов.
Ответ №1:
SELECT SUM(i.value)
FROM shelfTable s
JOIN inventoryTable i
ON i.shelfId = s.shelfId
WHERE s.shopId = 1
Ответ №2:
Это фундаментальный вопрос об отношениях между таблицами, поэтому я приведу некоторые подробности, надеясь, что вы сможете использовать некоторые из этих идей при написании SQL-запросов в будущем.
Давайте сначала начнем с одной базовой вещи. [shopId] может ссылаться на два разных, но связанных столбца, один в [ShopTable] и один в [ShelfTable]. То же самое относится и к [ShelfID]. Полезно всегда указывать таблицу.
Вы описываете [shopId] и [ShelfID] как «отношения». Как прокомментировал Damien_The_Unbeliever, эти столбцы фактически представляют собой две пары первичного и внешнего ключей. То есть [ShelfTable].[ShelfID] идентифицирует запись «shelf» и [InventoryTable].[ShelfID] связывает «элемент инвентаря» (что бы это ни было) с «полкой». (Не всегда возможно интерпретировать строки в базе данных таким наивным образом, но я готов предположить, что я не слишком далек от реальности.)
Аналогично, каждая «полка» принадлежит одному «магазину» и [ShelfTable].[shopId] относится к этому конкретному «shop». Обратите внимание, что, поскольку у нас уже есть значение [shopId] (я буду называть его «@MyShopID»), нам даже не нужна [ShopTable] здесь. Мы можем просто использовать [ShelfTable].[shopId] для фильтрации по интересующим нас «полкам».
Вы просите получить общую сумму [InventoryTable].[Значение] для одного значения [shopId], но [shopId] не отображается в [InventoryTable]. Вот где вступает в игру ваше (внутреннее) объединение. Вы знаете, что будете суммировать значения из [InventoryTable], но вы должны указать конкретный «магазин». Вы указываете @MyShopID для [ShelfTable].[ShelfID], который выполнит вашу фильтрацию в [InventoryTable] за вас.
И последнее, перед составлением запроса. Я предполагаю, что вы не слишком упростили свои таблицы, и что [Value] — это общая стоимость каждого «элемента инвентаря», а не просто значение единицы. Если бы это было не так, нам пришлось бы умножать значения на величины и т.д., Но я позволю вам проверить вашу собственную работу здесь.
Итак, вот что мы делаем:
- Мы выбираем
FROM
[InventoryTable]
- но мы
INNER JOIN
обращаемся к[ShelfTable]
on [ShelfID] из обеих таблиц - и нам нужны только «полки» из одного «магазина», т.Е.
WHERE [ShelfTable].[ShopID] = @MyShopID
- и тогда мы
SELECT
SUM([InventoryTable].[Value])
и мы закончили. В SQL давайте уберем скобки, предоставим некоторые псевдонимы таблиц, и мы получим запрос, который выглядит следующим образом:
SELECT SUM(inv.Value)
FROM InventoryTable AS inv
INNER JOIN ShelfTable AS shf ON shf.ShelfID = inv.ShelfID
WHERE shf.ShopID = @MyShopID
;
Вот несколько важных моментов, которые следует учитывать. Обратите внимание, что сначала мы обработали предложение FROM . Вы всегда будете хотеть это делать.
Вам также понадобится «управляющая таблица» для начала, в данном случае [InventoryTable]. Другие таблицы в вашем объединении добавляют дополнительную информацию и предоставляют вам средства для фильтрации, но в остальном не мешают вашему подведению итогов. Более сложные запросы не предлагают такой очевидной роскоши, но здесь мы не слишком увлекаемся.
Вы также заметите, только вкратце, что, поскольку [ShelfID] является первичным ключом в [ShelfTable], эти [ShelfID] являются уникальными значениями в [ShelfTable], и поэтому каждая «инвентарная» вещь принадлежит одной «полке». Таким образом, объединение не приведет к двойному подсчету значений. Это полезно помнить, когда вы не имеете дело с первичными и внешними ключами, как мы делаем здесь.
Надеюсь, это поможет. И я надеюсь, что я не показался вам слишком педантичным.
Комментарии:
1. Не слишком педантично, это отличное объяснение, спасибо!! И да, значение упрощено, на самом деле это СУММА ([Количество] * [Цена] / [PriceUnit] * [взвешивание]), но это была самая простая часть 🙂
2. Спасибо! И уфф, это много etc. чтобы разобраться! 🙂