Swimset_styletag

id          swimset_id  styletag_id
----------  ----------  -----------
1           1           1          
2           2           2          
3           3           1          
4           3           2    

Купальный костюм

id          set_description        
----------  -----------------------
1           4 x 100 Free Interval A
2           4 x 100 Back Interval A
3           6 x 100 free/back on in

Метка стиля

id          tag_name  
----------  ----------
1           Free      
2           back  

Я пытаюсь запросить swimsets, у которых нет styletag 2., чтобы они установили только то, что возвращаемое значение должно быть swimset_id 1. Однако, когда я пытаюсь использовать:

SELECT swimset_id, set_description, styletag_id
FROM swimset, swimset_styletag, styletag
WHERE
swimset.id = swimset_styletag.swimset_id AND swimset_styletag.styletag_id = styletag.id AND
swimset.styletag_id !=2;

Я получаю swimset_id 1 И 3, а не просто swimset_id 1. Я полагаю, это потому, что в swimset_styletag, swimset_id 3 имеет две записи, одна из которых соответствует styletag_id 1, а другая - styletag_id 2. Есть ли способ обработать обе записи swimset_id в swimset_styletag как одна запись?

Если это то, что следует решить с помощью другого дизайна базы данных, я также открыт для любых предложений, поскольку я все еще разрабатываю точный дизайн. Когда я создавал прототип некоторых скриптов Python без базы данных, я изначально использовал фиктивные данные как значения True / False в паре с ключами для каждого тега стиля. Если бы я просто добавил эти теги стиля как записи True / False в таблицу swimset, это позволило бы создать плоскую базу данных, но кажется более уродливым? Что-то вроде этой плохой практики по сравнению с множеством тегов стилей?

0
InfinteScroll 11 Мар 2014 в 09:50

1 ответ

Лучший ответ

Я думаю, это то, что вам нужно:

SELECT swimset.id, swimset.set_description, swimset_styletag.styletag_id
FROM swimset_styletag INNER JOIN
    swimset on swimset_styletag.swimset_id=swimset.id INNER JOIN 
    styletag on swimset_styletag.styletag_id=styletag.id
WHERE
swimset_id NOT IN (select swimset_id from swimset_styletag WHERE styletag_id=2)

См. Результат в SQL Fiddle

Для удаления нескольких styletag_id:

SELECT swimset.id, swimset.set_description, swimset_styletag.styletag_id
FROM swimset_styletag INNER JOIN
    swimset on swimset_styletag.swimset_id=swimset.id INNER JOIN 
    styletag on swimset_styletag.styletag_id=styletag.id
WHERE
swimset_id NOT IN (select swimset_id from swimset_styletag WHERE styletag_id IN (2,3,4,5,6))
3
Raging Bull 11 Мар 2014 в 10:32
Я собирался принять это, но похоже, что он все еще возвращает и swimset 1, и swimset 3. Я бы хотел, чтобы sql отфильтровывал swimset3 из-за того, что у него есть styletag 2 в одной из его записей для swimset_styletag
 – 
InfinteScroll
11 Мар 2014 в 10:06
Спасибо. Это действительно работает. Однако предположим, что у меня получается 20 тегов стиля, и в каждом наборе не менее 10. Если я хочу исключить любой набор для плавания с тегом стиля 1, мне нужно написать еще 9 операторов AND swimset_id NOT IN (...) ? Если да, то, может быть, более плоский дизайн базы данных будет лучше?
 – 
InfinteScroll
11 Мар 2014 в 10:20
Кстати, нам не нужно условие swimset.styletag_id !=2;. К вашему сведению, вы можете изменить WHERE styletag_id=2 на WHERE styletag_id IN (2,3,4,5,6).
 – 
Raging Bull
11 Мар 2014 в 10:25