#sql #inner-join
#sql #внутреннее соединение
Вопрос:
Я новичок в SQL.
У меня 3 таблицы:
TB_ITEM
{
TB_ITEM_ID int primary key,
TB_ITEM_CAT_ID int,
TB_ITEM_SUBCAT_ID int,
TB_ITEM_NAME varchar(350)
add constraint FK_ITEM_CAT foreign key(TB_ITEM_CAT_ID)
references TB_ITEM_CAT(TB_ITEM_CAT_ID),
add constraint FK_ITEM_SUBCAT foreign key(TB_ITEM_SUBCAT_ID)
references TB_ITEM_SUBCAT(TB_ITEM_SUBCAT_ID)
}
TB_ITEM_CAT
{
TB_ITEM_CAT_ID int primary key,
TB_ITEM_CAT_NAME varchar(350)
}
TB_ITEM_SUBCAT
{
TB_ITEM_SUBCAT_ID int primary key,
TB_ITEM_CAT_ID int,
TB_ITEM_SUBCAT_NAME
add constraint FK_CAT foreign key(TB_ITEM_CAT_ID)
references TB_ITEM_CAT(TB_ITEM_CAT_ID)
}
ТАБЛИЦА «TB_ITEM» СОДЕРЖИТ 416 ЗАПИСЕЙ.
Я пробовал, следуйте запросу:
select a.TB_ITEM_NAME, b.TB_ITEM_CAT_NAME, c.TB_ITEM_SUBCAT_NAME from
TB_ITEM a inner join
TB_ITEM_CAT b on a.TB_ITEM_CAT_ID = b.TB_ITEM_CAT_ID
inner join TB_ITEM_SUBCAT c
on a.TB_ITEM_SUBCAT_ID = c.TB_ITEM_SUBCAT_ID
и результат: 1162 результата
Я имею в виду: я хочу получить только эти 416 записей из TB_ITEM и его ИМЕН КАТЕГОРИЙ и ПОДКАТЕГОРИЙ из TB_ITEM_CAT и TB_ITEM_SUBCAT
Этот запрос неверен?Почему 1162 записи вместо только 416?
Есть идеи?
Комментарии:
1. Если есть несколько строк
TB_ITEM
, для которых есть одна и та же записьTB_ITEM_SUBCAT_ID
, то они будут совпадать несколько раз со столбцом с тем же именемTB_ITEM_SUBCAT_NAME
. На первый взгляд, это, вероятно, проблема.2. Попробуйте добавить a
group by 1,2,3
в конце вашего запроса. Проблема может заключаться в том, что у вас есть повторяющиеся строки.3. при группировании по количество результатов равно 1152. -10
4. Насколько я знаю, запрос должен работать, поля соединения являются первичными ключами, поэтому не должно быть дубликатов. Но не работает, поэтому я что-то упустил…
5. Может ли элемент принадлежать к нескольким категориям?
Ответ №1:
У вас TB_ITEM
есть два FK
add constraint FK_ITEM_CAT foreign key(TB_ITEM_CAT_ID)
references TB_ITEM_CAT(TB_ITEM_CAT_ID)
add constraint FK_ITEM_SUBCAT foreign key(TB_ITEM_SUBCAT_ID)
references TB_ITEM_SUBCAT(TB_ITEM_SUBCAT_ID)
И ваши соединения совпадают
from
TB_ITEM a inner join
inner join TB_ITEM_CAT b
on a.TB_ITEM_CAT_ID = b.TB_ITEM_CAT_ID
inner join TB_ITEM_SUBCAT c
on a.TB_ITEM_SUBCAT_ID = c.TB_ITEM_SUBCAT_ID
Это означает, что количество строк вашего запроса должно быть меньше или равно количеству таблиц.
Таким образом, это оставляет следующие возможности…
- Ваш подсчет таблицы неверен
- Опубликованные соединения в вашем запросе не соответствуют тому, что вы пытаетесь
- В вашем соединении есть что-то еще, чего мы не видим
- Вы не ссылаетесь на объект, который, по вашему мнению, ваш. (возможно, представление или синоним)
- Или ваш первичный ключ или внешний ключ — это не то, что вы говорите. например, ваш ключ является составным ключом
Попробуйте добавить имена схем, например dbo.TB_ITEM
, к вашим таблицам в предложении from и перепроверить остальные.
Комментарии:
1. Я рад, что вы решили свою проблему. Я обновил свой ответ, включив в него другую возможность того, что то, что вы опубликовали о ключах, было неточным (как смог выяснить Раджив). Я оставляю этот ответ на тот случай, если это может помочь кому-то в будущем. Кроме того, в качестве исключения вы, вероятно, захотите ссылаться на ответы с помощью плаката, а не «выше» или «ниже», поскольку позиция может измениться.
Ответ №2:
Вам нужно будет убедиться, что TB_ITEM_SUBCAT соединен правильно, чтобы избежать дублирования
Посмотрите, работает ли это:
select a.TB_ITEM_NAME, b.TB_ITEM_CAT_NAME, c.TB_ITEM_SUBCAT_NAME from
TB_ITEM a inner join
TB_ITEM_CAT b on a.TB_ITEM_CAT_ID = b.TB_ITEM_CAT_ID
inner join TB_ITEM_SUBCAT c
on a.TB_ITEM_SUBCAT_ID = c.TB_ITEM_SUBCAT_ID and a.TB_ITEM_CAT_ID = c.TB_ITEM_CAT_ID
Комментарии:
1. ВАУ! Теперь это работает! Я имею в виду, в чем была проблема? Можете ли вы объяснить?
2. Я заметил, что таблица TB_ITEM_SUBCAT имеет внешний ключ к таблице TB_ITEM_CAT, что навело меня на подозрение, что TB_ITEM_SUBCAT_ID может не быть первичным ключом для таблицы. Первичный ключ, вероятно, представляет собой комбинацию TB_ITEM_CAT_ID и TB_ITEM_SUBCAT_ID. Таким образом, соединение из TB_ITEM должно проверять равенство для обоих столбцов. Вероятно, вы могли бы убедиться в этом, просмотрев данные в таблице TB_ITEM_SUBCAT.
Ответ №3:
Происходит то, что в результатах создается запись для каждого раза, когда элемент соответствует категории / подкатегории. Так, например, если элемент A имеет 3 категории, к которым он принадлежит, результаты будут включать 3 экземпляра элемента A, соответствующие каждой из этих категорий. Естественно, это усугубляется таблицей подкатегорий, а также присоединением к ней. Если бы элемент имел 3 категории и 2 подкатегории, это вернуло бы 6 результатов!
Если вам все равно, какую категорию и / или подкатегорию вы выбираете для определенного элемента, вы можете просто сделать что-то вроде этого:
select a.TB_ITEM_NAME, b.TB_ITEM_CAT_NAME, c.TB_ITEM_SUBCAT_NAME from
TB_ITEM a inner join
TB_ITEM_CAT b on a.TB_ITEM_CAT_ID = b.TB_ITEM_CAT_ID
inner join TB_ITEM_SUBCAT c
on a.TB_ITEM_SUBCAT_ID = c.TB_ITEM_SUBCAT_ID
GROUP BY a.TB_ITEM_ID
Кроме того, если вы просто хотите получить один экземпляр каждого элемента и список категорий, подкатегорий, разделенных запятыми, я ДУМАЮ, что должно сработать что-то вроде этого:
select a.TB_ITEM_NAME, GROUP_CONCAT(b.TB_ITEM_CAT_NAME), GROUP_CONCAT(c.TB_ITEM_SUBCAT_NAME) from
TB_ITEM a inner join
TB_ITEM_CAT b on a.TB_ITEM_CAT_ID = b.TB_ITEM_CAT_ID
inner join TB_ITEM_SUBCAT c
on a.TB_ITEM_SUBCAT_ID = c.TB_ITEM_SUBCAT_ID
GROUP BY a.TB_ITEM_ID
Я надеюсь, что это поможет вам понять!