SQL простое внутреннее соединение

#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
  

Это означает, что количество строк вашего запроса должно быть меньше или равно количеству таблиц.

Таким образом, это оставляет следующие возможности…

  1. Ваш подсчет таблицы неверен
  2. Опубликованные соединения в вашем запросе не соответствуют тому, что вы пытаетесь
  3. В вашем соединении есть что-то еще, чего мы не видим
  4. Вы не ссылаетесь на объект, который, по вашему мнению, ваш. (возможно, представление или синоним)
  5. Или ваш первичный ключ или внешний ключ — это не то, что вы говорите. например, ваш ключ является составным ключом

Попробуйте добавить имена схем, например 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
  

Я надеюсь, что это поможет вам понять!