Учитывая 3 таблицы, такие как:
[Table_Main] ----> [Table_Sub] ----> [Table_Prop]
1-N 0-N
Я хочу выбрать элемент в [Table_Main]
, который :
- Иметь несколько [Table_Sub]
.
- со строками [Table_Sub]
, в которых есть и [Table_Prop]
, и нет.
Чтобы выбрать это значение, я использую:
SELECT Table_Main.Field_ID
FROM Table_Main
INNER JOIN Table_Sub on Table_Main.Field_ID = Table_Sub.Table_Main_Field_ID
LEFT JOIN Table_Prop on Table_Sub.Field_ID = Table_Prop.Table_Sub_Field_ID
Если мы переименуем таблицу Family, Child и Pet. Мне нужна семья, где у некоторых детей есть домашние животные, а у некоторых детей нет.
Семья: идентификатор, имя
1, Foo -- Family with 2 childs, one of them has a pet
2, Bar -- Family with 2 childs, 0 pet
3, Abc -- Family with 2 childs, both have pet
Ребенок: идентификатор, Family_Id, имя
1, 1, John -- Child of Foo
2, 1, Joe -- Child of Foo
3, 2, Jane
4, 2, Jessica
5, 3, XXX
6, 3, YYY
Питомец: Id, Child_Id, Имя
1, 2, FooBar -- Joe's pet
2, 5, Huey
3, 6, Dewey
Ожидаемый результат: 1, Фу
Семья с менее чем 2 детьми исключена из примера, если они могут удовлетворить оба ограничения:
- Есть ребенок с домашним животным
- Имеет ребенка без домашних животных.
CREATE TABLE Family(
1 INTEGER NOT NULL PRIMARY KEY
,Foo VARCHAR(20) NOT NULL
);
INSERT INTO Family(1,Foo) VALUES (1,'Foo');
INSERT INTO Family(1,Foo) VALUES (2,'Bar');
INSERT INTO Family(1,Foo) VALUES (3,'Abc');
CREATE TABLE Child(
Id INTEGER NOT NULL PRIMARY KEY
,Family_Id INTEGER NOT NULL
,Name VARCHAR(20) NOT NULL
);
INSERT INTO Child(Id,Family_Id,Name) VALUES (1,1,'John');
INSERT INTO Child(Id,Family_Id,Name) VALUES (2,1,'Joe');
INSERT INTO Child(Id,Family_Id,Name) VALUES (3,2,'Jane');
INSERT INTO Child(Id,Family_Id,Name) VALUES (4,2,'Jessica');
INSERT INTO Child(Id,Family_Id,Name) VALUES (5,3,'XXX');
INSERT INTO Child(Id,Family_Id,Name) VALUES (6,3,'YYY');
CREATE TABLE Pet(
Id INTEGER NOT NULL PRIMARY KEY
,Family_I INTEGER NOT NULL
,Name VARCHAR(20) NOT NULL
);
INSERT INTO Pet(Id,Family_Id,Name) VALUES (1,2,'FooBar');
INSERT INTO Pet(Id,Family_Id,Name) VALUES (2,5,'Huey');
INSERT INTO Pet(Id,Family_Id,Name) VALUES (3,6,'Dewey');
Вопрос тоже не помешал бы.
Демонстрационные данные лучше всего использовать как DDL + ДМЛ. Пожалуйста, редактировать ваш вопрос, чтобы включить его, вашу текущую попытку и желаемые результаты. Для получения дополнительной информации прочитай это.
@ZoharPeled, хотя я достаточно упростил вопрос, чтобы сделать его ясным, общим и независимым от данных. Но чтение «и» как не исключающего приводит людей к мысли, что я пропустил группу.
Я не знаю, почему ты обращаешься ко мне. Я не сказал, что вопрос не простой, я только сказал, что для этого нужны образцы данных. IMO, если вы уже удосужились отредактировать свой вопрос с помощью образца данных, вам следовало приложить дополнительные усилия и предоставить его как DDL + DML.
Извините за пинг, я могу пинговать только одного пользователя на комментарий, я взял последний. Я предоставлю скрипку sql в следующий раз. Я просто не люблю DDL+DML. в простой вопрос, потому что они едят, чтобы занять место без всякой причины.
Скрипка - это хорошо и все такое, но хороший вопрос самодостаточен - по тем же причинам, по которым ответы только на ссылки имеют низкое качество: ссылки не всегда доступны. Для получения дополнительной информации: Почему я должен предоставлять MCVE для того, что мне кажется очень простым SQL-запросом?
@ZoharPeled, Done, было отложено из-за того, что SqlFiddle все еще не работает. Поэтому я создаю регулярное выражение для анализа и вывода скрипта. Я понимаю правила, я понимаю, почему до сих пор считаю текущую версию уродливой по моему стандарту.
Это даст вам желаемый результат.
;with family as
(
select 1 FamilyID, 'Foo' Family union select 2, 'Bar' union select 3, 'ABC'
), child as
(
select 1 ChildID, 1 FamilyID ,'John' ChildName union
select 2, 1, 'Joe' union
select 3, 2, 'Jane' union
select 4, 2, 'Jessica' union
select 5, 3, 'XXX'union
select 6, 3, 'YYY'
), pets as
(
select 1 petid , 2 childid, 'FooBar' pet union
select 2, 5, 'Huey' union
select 3, 6, 'Dewey'
)
SELECT T.FamilyID, Max(Family) Family, MIN(CNT) [Min] , MAX(CNT) [Max] FROM
(
SELECT f.FamilyID, C.ChildID, SUM(case when petid is null then 0 else 1 end) CNT FROM Family F
JOIN Child C ON F.FamilyID = C.FamilyID
LEFT JOIN Pets P ON C.ChildID = P.ChildID
GROUP BY F.FamilyID, C.ChildID
) T JOIN Family F on T.FamilyID = F.FamilyID GROUP BY T.FamilyID
HAVING MIN(CNT) = 0 AND MAX(CNT) > 0
Спасибо, собирался прокомментировать, что счетчик возвращает единицу при нулевом значении, но вы его отредактировали. 2 groupy by - это решение, которое я пытался получить от внутреннего запроса. Большое спасибо за ваше время.
если решение сработало для вас @xdtTransform, примите его как ответ.
Всегда просматривайте все мои действия StackOverflow в конце недели. Я обычно принимаю ответ в этот момент.
похоже, вы близки, но если я правильно понимаю:
With parent as (
select 'Charlie' name from dual union all
select 'Ben' name from dual union all
select 'Bob' name from dual union all
select 'Harry' name from dual
)
,child as (
select 'Ben' parentname, 'Bebbie' name from dual union all
select 'Ben' parentname, 'Tilda' name from dual union all
select 'Bob' parentname, 'Shara' name from dual union all
select 'Bob' parentname, 'Sandra' name from dual
)
,pet as (
select 'Tilda' childname, 'Dog' pet from dual union all
select 'Tilda' childname, 'Cat' pet from dual union all
select 'Shara' childname, 'Bird' pet from dual union all
select 'Shara' childname, 'Snake' pet from dual
)
select pa.name,ch.name,count(pe.pet)
from parent pa
inner join child ch on ch.parentname = pa.name
left join pet pe on pe.childname = ch.name
group by pa.name,ch.name
Запрос
select family.ID, family.name
from family
left join child on family.ID = child.family_id
left join pet on pet.child_ID = child.Id
group by family.name,family.ID
having count(child.id) > 1 and count( pet.id) <>0 and count(child.id) > count( pet.id)
Выход
Привет, пожалуйста, объясните свой ответ, почему это будет решением проблемы OP. Это поможет ОП и будущим посетителям сайта. Спасибо!
Привет, я изменил запрос в соответствии с последней информацией, представленной в описании вопроса. Надеюсь это поможет.
Да, просто и работает. почему-то пропустил count(child.id) > count( pet.id)
.
Образцы данных и ожидаемые результаты помогут другим понять вашу цель.