3eta: (Default)
[personal profile] 3eta
SQL-оведы, помогите. Нужно сделать запрос, где мне очень хочется вставить цикл, но ведь наверное нельзя?
Звучит просто: выбрать из таблицы с именами и фамилиями людей, у которых фамилия такая же как у кого-либо другого имя. Все идеи закончились, ничего не работает (в том числе по каким ключевым словам гуглить возможные решения).

Date: 2012-09-29 07:07 pm (UTC)
From: [identity profile] w1ad.livejournal.com
Не на чем попробовать ... дома нет СУБДшек ...

может так (подзапрос в запросе)?

select * from tab where fam = (select nam from tab)
где поле "fam" должно быть по длинне равно "nam"

Date: 2012-09-29 07:12 pm (UTC)
From: [identity profile] 3eta.livejournal.com
пробовала, выдает #1242 - Subquery returns more than 1 row
:(

Date: 2012-09-29 07:34 pm (UTC)
From: [identity profile] machin.livejournal.com
select * from tab where fam IN (select nam from tab)

Date: 2012-09-29 07:36 pm (UTC)
From: [identity profile] 3eta.livejournal.com
Yay! Заработало! Спасибо большое :)
А я уж начала сомневаться, что вложенный запрос вообще имеет право а существование из-за текста ошибки.

Date: 2012-09-29 07:37 pm (UTC)
From: [identity profile] machin.livejournal.com
обращайся)

Date: 2012-09-29 07:38 pm (UTC)
From: [identity profile] 3eta.livejournal.com
хаха, ща поломаю голову над оставшимися задачками и, может, обращусь еще :)

Date: 2012-09-29 07:39 pm (UTC)
From: [identity profile] machin.livejournal.com
Кстати, можно попробовать ускорить этот запрос. Но это тебе вряд ли нужно.

Date: 2012-09-29 08:58 pm (UTC)
From: [identity profile] 3eta.livejournal.com
Вот еще один похожий:
Many times, a son has the same name as his father. (George Abbott had a son named George.) Find all such pairs, and list their names, the father's birth date, and the son's birth date.

Получается только выбрать всех, у кого в принципе есть отцы (father.person.id), а вот как смэтчить с именами отцов - не понимаю.

Date: 2012-09-29 10:51 pm (UTC)
From: [identity profile] jgofri.livejournal.com
А как определяется, кто чей отец? Is there a recursive relationship in that table?

Date: 2012-09-29 10:52 pm (UTC)
From: [identity profile] 3eta.livejournal.com
да, таблица выглядит как
Person_ID
First_Name
Last_Name
...
Father_Person_ID
Mother_Person_ID

Date: 2012-09-29 11:06 pm (UTC)
From: [identity profile] jgofri.livejournal.com
I may be rusty on the syntax, but I think something like this will work:

select t1.last_name, t1.first name, t1.dob "son dob", t2.dob "dad dob"
from Table t1, Table t2
where t1.father_person_id = t2.person_id
and t1.first_name = t2.first_name

Date: 2012-09-29 07:38 pm (UTC)
From: [identity profile] mme-n-b.livejournal.com
select t1.LastName, t2.FirstName
from Table as t1
inner join Table as t2 --this is the same table
on t1.LastName=t2.FirstName

Date: 2012-09-29 08:59 pm (UTC)
From: [identity profile] 3eta.livejournal.com
я вот читаю про join-ы, но пока так и не осмыслила в какой ситуации их надо применять. точнее, мне казалось, что в ситуации когда у тебя две таблицы?

Date: 2012-09-29 10:50 pm (UTC)
From: [identity profile] jgofri.livejournal.com
а в данном случае тут как бы "две таблицы", t1 and t2. SQL will work with them as if they were different tables.
"join" is not something stable, it's a way for SQL to match one set of records with the other.
You use inner join when you want all records from one table and only matching records from the other one.

Date: 2012-09-29 10:53 pm (UTC)
From: [identity profile] 3eta.livejournal.com
то есть когда надо обработать одну таблицу как две разных? запуталась.
у меня-то одна таблица :)

Date: 2012-09-29 11:02 pm (UTC)
From: [identity profile] jgofri.livejournal.com
Я не уверена, что ты называешь "обработать", но система создаст в памяти, если я правильно помню, две отдельные временные таблицы
Если бы было две таблицы, ты бы писала:

select * from table1, table 2 where table1.id = table2.id
система грузит обе таблицы в память и гоняет алгоритм.

а так пишешь
select * from table as table1, table as table2
система грузит две таблицы в память, точно так же, но они одинаковые.

Это я очень поверхностно и нарочито упрощенно объясняю, конечно.

Date: 2012-09-29 11:17 pm (UTC)
From: [identity profile] 3eta.livejournal.com
спасибо! мне как раз поверхностно и не хватает, потому что я могу скопировать и применить чужой запрос, но мне бы понять принцип - как оно работает и почему стоит именно так

Date: 2012-09-29 11:35 pm (UTC)
From: [identity profile] machin.livejournal.com
Давай я ещё попробую.

Представь, что тебе нужно решить задачу с одноименным отцом на бумаге.
(Вживемся в роль СУБД)
У тебя есть листок с таблицей
номер человека | ФИО | Дата рождения | Номер отца
Проблема в том, что ты можешь смотреть в один момент только на одну строчку таблицы. Зато можно заглядывать в другие таблицы, не забывая строчку из первой

Поэтому ты идешь к ксероксу и делаешь копию этого листа. Теперь у тебя две одинаковые копии одной таблицы. Ты помечаешь их как Тable1 и Тable2, чтобы не перепутать.

На этом этапе у нас есть запрос:
select * from table as table1, table as table2

Теперь можно приступить к решению непосредственно задачи.
Ты берешь первую строчку из первой таблицы и сравниваешь с каждой строчкой второй таблицы.
Что ты ищешь?
В первой таблице у нас сын, во второй таблице ты ищешь его отца.
Это означает, что ты берешь номер отца из первой таблицы и сравниваешь с просто номером из второй. Тебе подходят только пары, где эти два номера равны.

На этом этапе у нас есть запрос:
select * from table as table1, table as table2
WHERE table1.Father_Person_ID = table2.ID

Но в получившемся списке у тебя по-прежнему есть лишние пары!
Теперь при сравнении строчка-строчка ты проверяешь еще одно условие: имя отца и сына одинаковое.
Теперь у нас есть запрос
select * from table as table1, table as table2
WHERE table1.Father_Person_ID = table2.ID
AND table1.first name = table1.first name

Это и есть наш окончательный запрос.

Мы поставили AND, потому что нам нужно, чтобы оба условия выполнялись вместе.

И на всякий случай уточню: Тable1 и Тable2 - твои личные выдуманные пометки, ты могла их назвать sdgsdfgsdfgdsfg1 и gogogogog.

Date: 2012-09-29 11:50 pm (UTC)
From: [identity profile] 3eta.livejournal.com
Супер, теперь все встало на свои места!
Спасибо большое.
А ты еще не спишь или уже не спишь? У вас там 2 ночи!

Date: 2012-09-30 12:35 am (UTC)
From: [identity profile] 3eta.livejournal.com
что-то не то :-/
SELECT * FROM `People` as `table1`, `People` as `table2` WHERE `table1`.`Father_Person_ID` = `table2`.`Person_ID`
AND `table1`.`First_Name` = `table1`.`First_name`;
возвращает мне список всех людей у которых есть отцы, так же как мой предыдущий запрос со вложенным select-ом, непонятно где собака зарыта. перепроверила все названия колонок :-/

Date: 2012-09-29 11:15 pm (UTC)
From: [identity profile] mme-n-b.livejournal.com
Используйте join всегда, когда в задаче есть фраза <такой же, как>. Не заморачивайтесь пока тем, как они работают на самом деле.

Date: 2012-09-29 11:16 pm (UTC)
From: [identity profile] mme-n-b.livejournal.com
that's a left join. inner is only matching in both.

Date: 2012-09-29 11:18 pm (UTC)
From: [identity profile] jgofri.livejournal.com
You are right, sorry.
normally I just use = for regular join.
I do remember that's slightly different in Oracle and SQL server, but don't remember which one is which.

Date: 2012-09-30 02:21 pm (UTC)
From: [identity profile] mme-n-b.livejournal.com
And a pain in both :)

Date: 2012-09-29 11:10 pm (UTC)
From: [identity profile] mme-n-b.livejournal.com

in this case you view one table as two.

Date: 2012-09-29 10:26 pm (UTC)
From: [identity profile] anglerhood.livejournal.com
В стандартном (ANSI) SQL нет явных циклов и вообще он не Тьюринг полный, поэтому некоторые приёмы из других языков в нём не работают. Но в реальных условиях используют расширенния SQL для конкретной СУБД, типа T-SQL для MS SQL или PL/SQL для Oracle, в этих расширенных языках уже всё можно :)

Date: 2012-09-29 10:49 pm (UTC)
From: [identity profile] 3eta.livejournal.com
да, я догадывалась, осталось разобраться как же подобные задачи решаются в sql без циклов)

Date: 2012-09-30 05:11 am (UTC)
From: [identity profile] hettie-lz.livejournal.com
Постарайтесь найти время и прочитать хороший учебник по реляционной теории, потому что иначе Вы сейчас всякого тут "нахватаетесь". и потом сто специалистов не оптимизируют :)))

Date: 2012-09-30 05:21 am (UTC)
From: [identity profile] 3eta.livejournal.com
Да вот пытаюсь читать, но идет тяжело, усваивается не с первого прочтения. Надо возвращаться и перечитывать по несколько раз - нам в первую же неделю 3 главы дали, и пары часов в день не хватает.

Date: 2012-09-30 10:43 am (UTC)
From: [identity profile] hettie-lz.livejournal.com
Если Вам это дали как учебное задание, то про JOINS уже должно было быть объяснено:). На какой СУБД Вам надо упражнения делать? По какой книжке Вы занимаетесь?
Edited Date: 2012-09-30 10:43 am (UTC)

Date: 2012-09-30 05:14 pm (UTC)
From: [identity profile] 3eta.livejournal.com
Это онлайн-курс, поэтому преподаватель дает только notes, лекций устных нет.
Книга Database Processing автор David Kroenke. Про Joins речь идет во второй главе, но именно в аспекте поиска по двум и более таблицам, остальное по join должно быть в 7 главе, которую нам пока не задавали :)

Выбор конкретной СУБД оставили на наше усмотрение, я выбрала MySQL поскольку работала с ним раньше.

Date: 2012-10-01 01:06 am (UTC)
From: [identity profile] hettie-lz.livejournal.com
ага, понятно. На самом деле, если про JOIN уже было, то этого достаточно. Тут фишка в том, что одна таблица выступает в двух ролях. А может и в большем количестве ролей. Можно сказать - это два экземпляра одной таблицы.

Profile

3eta: (Default)
3eta

September 2021

S M T W T F S
   1234
567891011
12131415161718
19 202122232425
2627282930  

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jun. 23rd, 2025 07:47 pm
Powered by Dreamwidth Studios