Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2  Все   Вниз
  Печать  
Автор Тема: SQL-запрос для объединения таблиц  (Прочитано 52809 раз)
0 Пользователей и 9 Гостей смотрят эту тему.
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« : 11-01-2010 16:14 » 

У меня есть таблица:

 -------------------------------------------
|id | cod1      | cod2          | author |
 -------------------------------------------
|1 |88.1,81.2|771.09,77.1|petrov  |
|2 |88.1,83.2|771.09        |ivanov  |
|...|....           |....               |....        |
|n |....           |....               |....        |
 -------------------------------------------

Но таблица в столбцах cod1 и cod2 не удовлетворяет первой нормальной форме (1НФ).

1НФ - требует, чтобы каждое значение атрибута или столбца было атомарным.

Я это исправил так:

Таблица2:

 ---------------------------
|id | cod1  | author_id |
 ---------------------------
|1 |88.1    |1               |
|2 |81.2    |1               |
|3 |88.1    |2               |
|4 |83.2    |2               |
 ---------------------------

Таблица3:

 ---------------------------
|id | cod2  | author_id |
 ---------------------------
|1 |771.09|1               |
|2 |77.1    |1               |
|3 |771.09|2               |
 ---------------------------

Таблица1:

 --------------
|id | author |
 --------------
|1  |petrov  |
|2  |ivanov  |
 --------------

Тогда SQL-запрос можно сделать так:


Код:
SELECT a.cod1, b.cod2, c.author FROM Таблица2 AS a, Таблица3 AS b, Таблица1 AS c
RIGHT JOIN Таблица2 AS a on a.author_id=c.id
RIGHT JOIN Таблица3 AS b on b.author_id=c.id

А что делать, если у разных авторов может повторятся author_id в таблицах 2 и 3?

Тогда же author_id в таблицах 2 и 3 не будет совпадает с id из таблицы 1.
« Последнее редактирование: 11-01-2010 17:23 от zuze » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 11-01-2010 16:39 » 

а он не должен повторяться, по идее Улыбаюсь Если есть возможность - лучше создать ещё колонку с уникальным индексом

в таблице 1 id должен называться autor_id и быть уникальным
Записан

RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 11-01-2010 16:53 » 

zuze, убедительнейшая просьба: выкладывать не картинки с "радикала", а нормальный текст!

id - это что? Имена у таблиц есть или это полная абстракция?
« Последнее редактирование: 11-01-2010 16:57 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #3 : 11-01-2010 17:00 » 

Алексей1153++, сейчас я поясню более подробно, что я имею ввиду. Представьте, что есть исходная таблица, которую нужно нормализовать:

 -------------------------------------------
|id | cod1      | cod2          | author |
 -------------------------------------------
|1 |88.1,81.2|771.09,77.1|petrov  |
|2 |88.1,83.2|771.09        |ivanov  |
|3 |89           |200.01        |sushkin|
|4 |88.1,81.2|200.01        |            |
|...|....           |....               |....        |
|n |....           |....               |....        |
 -------------------------------------------

Как видно из этой таблицы у авторов petrov и vilkin совпадает cod1, а следовательно будет совпадать author_id.
Как видно из этой таблицы у авторов sushkin и vilkin совпадает cod2, а следовательно будет совпадать author_id.

И что же в таком случае делать?

 
« Последнее редактирование: 11-01-2010 17:29 от zuze » Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 11-01-2010 17:08 » 

zuze, не совсем понятно: ты хочешь вынести коды в отдельную таблицу со своими идентификаторами? А есть ли смысл? Не все и вся нужно нормализовывать. Рассмотри, что у тебя первично в отношениях объектов (повторяю вопрос: что такое id - чей id?).
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #5 : 11-01-2010 17:36 » 

Цитата: RXL
что такое id - чей id

В Таблице1 id - это уникальный идентификатор автора.
В Таблице2 id - это уникальный идентификатор строки, а author_id - это идентификатор кода (cod1) конкретного автора
В Таблице3 id - это уникальный идентификатор строки, а author_id - это идентификатор кода (cod2) конкретного автора

Может я вообще всё не так делаю и надо было всё, как-то иначе делать?

Цитата: RXL
Не все и вся нужно нормализовывать.

Как можно выяснить нужно или не нужно нормализировать?
« Последнее редактирование: 11-01-2010 17:42 от zuze » Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #6 : 11-01-2010 17:58 » 

zuze, Это ты решаеш сам. Есть примерная область применения твоей базы. И запросы, которые будут применяться к твоей базе. Ты должен определить. Какое построение данных будет наименее затратным. Также стоит обратить внимание на дальнейшее безболезненное увеличение. Так чтоб, на "я хочу" твоего начальника, тебе не пришлось полностью перелапачивать код.
« Последнее редактирование: 11-01-2010 18:01 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 11-01-2010 19:45 » 

zuze, вариантов несколько:

1. Оставить исходный вид.

2. Вынести коды в отдельную таблицу.

Код:
CREATE TABLE authors
(
  id INT PRIMARY KEY,
  name VARCHAR(100) NOT NULL
);

CREATE TABLE authors_codes
(
  author_id INT NOT NULL,
  code VARCHAR(10) NOT NULL,
  PRIMARY KEY (author_id, code)
);

3. Вынести коды в отдельный справочник и создать таблицу связи с авторами.

Код:
CREATE TABLE authors
(
  id INT PRIMARY KEY,
  name VARCHAR(100) NOT NULL
);

CREATE TABLE codes
(
  id INT PRIMARY KEY,
  code VARCHAR(10) NOT NULL
);

CREATE TABLE authors_codes
(
  author_id INT NOT NULL,
  code_id INT NOT NULL,
  PRIMARY KEY (author_id, code_id)
);

Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 11-01-2010 20:02 » 

Если cod1, cod2 обобщить до N, то появится ещё одна таблица.

Author(AuthorID,Name), где Name='petrov','ivanov',...
CodeType(CodeTypeID,Type), где Type=1,2,...
Code(CodeID,CodeTypeID,Value), где Value=88.1,771.09,...
Table(AuthorID,CodeID)

Но если в исходной таблице ID имеет какой-то смысл (например, важно, чтобы все перечисленные в cod1, cod2 полях коды логически относились к одной записи), то в Table добавится и это поле.

Возможно, CodeTypeID относится не к справочнику Code, а к основной таблице Table - это зависит от совпадения или несовпадения доменов у cod1, cod2 и т.д.
« Последнее редактирование: 11-01-2010 20:03 от Dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
McZim
Модератор

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #9 : 11-01-2010 21:39 » 

Как уже сказали вариантов масса. Единственно что нужно понять, то как будут наполняться таблицы/таблица, то есть какой будет объем данных и как потом с этими таблицами намерен работать? Какие нужны данные по каким условиям?

Кардинальных вариантов два. Оставить все в одной таблице (не так как сейчас) с одним уникальным полем id, или разнести на три таблицы, все остальное это вариации этих методов.

Задача не ясна.

RXL, второй вариант у тебя не верен, не понятно где какой код, я так понял что автору нужно четкое разграничение. Или я ошибаюсь?
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #10 : 11-01-2010 21:51 » 


например,

|id | author_id | flag|value|
----------------------------------
|1 |1               |cod1|88.1  |
|2 |1               |cod2|771.09|
|3 |1               |cod2|77.09|
если id не уникально.
если требуется уникальность записи
то еще одно поле id записи = id самой первой таблицы

1|1 |88.1|cod1|petrov  |
2|1 |81.2|cod1|petrov  |
3|1 |771.09|cod2|petrov  |
4|1 |77.1|cod2|petrov  |
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
McZim
Модератор

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #11 : 11-01-2010 22:04 » 

Sla, если ограничиваться одной таблицей, то id это и будет идентификатор уникально записи
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #12 : 11-01-2010 22:10 » 

в этом варианте есть определенное преимущество
1|1 |88.1|cod1|petrov  |
2|1 |81.2|cod1|petrov  |
3|1 |771.09|cod2|petrov  |
4|1 |77.1|cod2|petrov  |

его можно "улучшить"

CREATE TABLE authors
(
  id INT PRIMARY KEY,
  name VARCHAR(100) NOT NULL
);

CREATE TABLE codes
(
  id INT PRIMARY KEY,
  code VARCHAR(10) NOT NULL
);

CREATE TABLE values
(
  id INT PRIMARY KEY,
  id_record int,
  id_code int,
  id_authors int,
  value VARCHAR(10)
);
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
McZim
Модератор

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #13 : 11-01-2010 22:27 » 

имхо, лишнее это.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #14 : 11-01-2010 22:48 » 

Цитата: McZim
объем данных
Десятки тысяч, а может и сотни строк.

Цитата: McZim
как потом с этими таблицами намерен работать и какие нужны данные по каким условиям?
С ними будет работать скрипт таким образом, если пользователь выбирает конкретную фамилию, то выводится она и все коды относящиеся к этой фамилии.

Записан
McZim
Модератор

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #15 : 12-01-2010 08:19 » 

zuze, а как данные заносятся? Поля могут быть пустыми, если да то какие? Набор фамилий или кодов фиксированный?
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #16 : 12-01-2010 08:27 » 

Цитата:  McZim
Поля могут быть пустыми, если да то какие?

Поля cod1 или cod2 могут быть пустыми, но это редкий случай. 
Записан
McZim
Модератор

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #17 : 12-01-2010 09:14 » 

zuze, но все же могут!



* Screen shot 2010-01-12 at 12.13.31.png (57.89 Кб - загружено 1755 раз.)
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #18 : 12-01-2010 09:38 » 

McZim, к сожалению такой вариант не подходит, так как повторяется фамилия несколько раз, это было ничего страшного если бы был только столбец фамилия.

Дело в том, что я специально для примера упростил таблицу, а в реальной таблице ещё куча столбцов и если они все будут повторятся, таблица будет накапливать очень большой объём дублирующей информации.
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #19 : 12-01-2010 09:45 » 

Не, я так не играю Улыбаюсь

Тут что главное?
Думаю что вот это
1 |88.1,81.2|771.09,77.1|petrov  |....
т.е. id записи и другие
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
McZim
Модератор

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #20 : 12-01-2010 09:54 » 

zuze, я же говорю все зависит от того что нужно в итоге, я не знаю твоей задачи и твоих требований. Если не устраивает так, то разноси, как будешь разносить это тоже дело твое, так как id авторов могут тоже повторяться в таблицу.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #21 : 12-01-2010 09:58 » 

Sla, в основной таблице есть столбцы id cod1, cod2, author и куча ещё других столбцов которые относятся к конкретному автору, вот по этому я и не стал их указывать.

Если нужно для полноты картины написать полную таблицу, я с удовольствием это сделаю.
Записан
McZim
Модератор

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #22 : 12-01-2010 10:00 » 

zuze, ты лучше расскажи что ты хочешь сделать в итоге? Какая цель? И почему у тебя в таблице не могут повторяться авторы?
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #23 : 12-01-2010 10:07 » 

Цитата: McZim
что ты хочешь сделать в итоге? Какая цель?
Разработка информационно-поисковой системы

Цитата: McZim
почему у тебя в таблице не могут повторяться авторы?
Так как все другие поля столбцов которые я не указал для простоты тоже зависят от автора и их тоже придётся дублировать, а там приличный объём информации.
Записан
McZim
Модератор

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #24 : 12-01-2010 10:16 » 

Улыбаюсь У тебя так и так будет объем информации одинаков. Например ты разнесешь данные по таблицам, в одной из таблиц у тебя будет имя автора и его id в другой таблице куча записей для этого id. Если для одного автора сопоставима куча информации в разный момент времени, что ты хочешь куда разделить что бы не было дубля. Да и вообще я не вижу дубля, каждая запись уникальна. Если у тебя все же укладываются в БД одинаковые записи, то это уже вопрос не к БД.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #25 : 12-01-2010 10:31 » 

например
CREATE TABLE books
(
  id INT PRIMARY KEY,
  author VARCHAR(100) NOT NULL,
  name VARCHAR(100) NOT NULL
);
CREATE TABLE parameters
(
  id INT PRIMARY KEY,
  id_books int,
  name_parameter  VARCHAR(100) NOT NULL,
  value_parametr VARCHAR(100)
)

вижу такое

Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #26 : 12-01-2010 10:46 » 

У меня появилась такая идея, Таблица2 и Таблица3 остаётся без изменений, а Таблица1 имеет вид:

 -------------------------------
|id | cod1 | cod2 | author |
 -------------------------------
|1 |1        |1        |petrov  |
|2 |2        |2        |ivanov  |
|3 |3        |3        |sushkin|
|4 |1        |3        |vilkin    |
|...|....      |....      |....        |
|n |x        |y         |z          |
 -------------------------------

Как Вы считаете это хорошая идея?
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #27 : 12-01-2010 11:11 » 

не понятно
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #28 : 12-01-2010 11:19 » new

Код:
Таблица2:
 ---------------------------
|id_cod1 | cod1  | author_id |
 ---------------------------
|1 |88.1    |1               |
|2 |81.2    |1               |
|3 |88.1    |2               |
|4 |83.2    |2               |
 ---------------------------

Таблица3:
 ---------------------------
|id_cod2 | cod2  | author_id |
 ---------------------------
|1 |771.09|1               |
|2 |77.1    |1               |
|3 |771.09|2               |
 ---------------------------

Таблица1:

 --------------
|id_author | author |
 --------------
|1  |petrov  |
|2  |ivanov  |
 --------------
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #29 : 12-01-2010 11:21 » 

Sla, сейчас попробую пояснить более подробно.

Есть исходная таблица:

 -------------------------------------------
|id | cod1      | cod2          | author |
 -------------------------------------------
|1 |88.1,81.2|771.09,77.1|petrov  |
|2 |88.1,83.2|771.09        |ivanov  |
|3 |89           |200.01        |sushkin|
|4 |88.1,81.2|200.01        |vilkin    |
 -------------------------------------------

Таблица2:

 ---------------------------
|id | cod1  | author_id |
 ---------------------------
|1 |88.1    |1               |
|2 |81.2    |1               |
|3 |88.1    |2               |
|4 |83.2    |2               |
|5 |89       |3               |
 ---------------------------

Таблица3:

 ---------------------------
|id | cod2  | author_id |
 ---------------------------
|1 |771.09|1               |
|2 |77.1    |1               |
|3 |771.09|2               |
|4 |200.01|3               |
 ---------------------------

Таблица1:

 -------------------------------
|id | cod1 | cod2 | author |
 -------------------------------
|1 |1        |1        |petrov  |
|2 |2        |2        |ivanov  |
|3 |3        |3        |sushkin|
|4 |1        |3        |vilkin    |
 -------------------------------

Надеюсь так стала понятно. Как Вы считаете это хорошая идея?

Записан
Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines