Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Объединение трёх таблиц с условием / 15 сообщений из 15, страница 1 из 1
07.10.2013, 16:11:33
    #38419107
Странник61
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объединение трёх таблиц с условием
Помогите новичку.
Есть три таблицы:
partner(id, title),
person(id, partner_id, title, sort),
phone (id, person_id, value, sort_phone)

На выходе нужно получить:
partner.*, person.title (одного человека, где sort должно быть минимально), phone.value (один телефон, где sort_phone должно быть минимально)

Можно ли это сделать одним запросом типа такого:
SELECT partner.*, person.title as title2, person.sort as sort2, MIN(phone.sort_phone) AS sort_phone2, person_phone.value FROM partner, person, phone WHERE partner.id=person.partner_id AND person.id=phone.person_id GROUP BY partner.title ORDER BY partners.title

(Тут не знаю как назначить усливия).

Или нужны вложенные запросы?
...
Рейтинг: 0 / 0
07.10.2013, 17:15:48
    #38419229
hallabud
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объединение трёх таблиц с условием
Преждевременная оптимизация - это зло.
Напишите сначала рабочий запрос, а если не будет удовлетворять производительность, тогда пробуйте варианты.
...
Рейтинг: 0 / 0
07.10.2013, 23:09:52
    #38419529
Странник61
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объединение трёх таблиц с условием
Я как раз и не знаю как написать запрос.
Поэтому и спрашиваю совета.
...
Рейтинг: 0 / 0
08.10.2013, 01:01:17
    #38419572
hallabud
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объединение трёх таблиц с условием
Странник61,

если sort и sort_phone уникальны тогда ORDER BY и LIMIT
вы же написали запрос, чем он не подходит? запускать пробовали? :)

пример без вложенных
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
CREATE TABLE IF NOT EXISTS partner (id int PRIMARY KEY, title varchar(50));
CREATE TABLE IF NOT EXISTS person (id int PRIMARY KEY, partner_id int, title varchar(50), sort int);
CREATE TABLE IF NOT EXISTS phone (id int PRIMARY KEY, person_id int, value varchar(50), sort_phone int);

INSERT INTO partner VALUES 
 (1, 'Гугл инкорпорейтед'),
 (2, 'Майкрософт'),
 (3, 'Эпл компутерс');

INSERT INTO person VALUES 
 (1, 1, 'Сергей Брин', 1),
 (2, 1, 'Ларри Пейдж', 2),
 (3, 2, 'Билл Гейтс', 1),
 (4, 2, 'Стив Балмер', 2),
 (5, 3, 'Стив Джобс', 1),
 (6, 3, 'Стив Возняк', 2);

INSERT INTO phone VALUES 
 (1, 1, '911', 1),
 (2, 1, '102', 2),
 (3, 2, '02', 1),
 (4, 2, '03', 2),
 (5, 3, '04', 1),
 (6, 3, '09', 2),
 (7, 4, '101', 1),
 (8, 4, '111', 2),
 (9, 5, '104', 1),
 (10, 5, '112', 2),
 (11, 6, '996', 1),
 (12, 6, '454', 2);


SET @partner_num=(SELECT COUNT(*) FROM partner);
PREPARE GET_PARTNERS_WITH_MIN_SORT FROM 
'
SELECT par.*, per.*, ph.*
FROM person per
 JOIN partner par ON per.partner_id = par.id
 JOIN phone ph ON per.id = ph.person_id
ORDER BY per.sort, ph.sort_phone, par.title
LIMIT ?;
';
EXECUTE GET_PARTNERS_WITH_MIN_SORT USING @partner_num;

DROP TABLE IF EXISTS partner;
DROP TABLE IF EXISTS person;
DROP TABLE IF EXISTS phone;

...
Рейтинг: 0 / 0
08.10.2013, 01:05:04
    #38419574
hallabud
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объединение трёх таблиц с условием
...
Рейтинг: 0 / 0
08.10.2013, 10:02:40
    #38419761
Странник61
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объединение трёх таблиц с условием
Тут как раз и есть проблема.
Как только добавляю GROUP BY partner.title то сортировка перестат работать.
В вашем примере ORDER BY ph.sort_phone и ASC, и DESC выдают одинаковый результат
SET @partner_num=(SELECT COUNT(*) FROM partner2);
PREPARE GET_PARTNERS_WITH_MIN_SORT FROM
'
SELECT par.*, per.*, ph.*
FROM person2 per
JOIN partner2 par ON per.partner_id = par.id
JOIN phone2 ph ON per.id = ph.person_id
GROUP BY par.title
ORDER BY ph.sort_phone DESC, per.sort, par.title
';
EXECUTE GET_PARTNERS_WITH_MIN_SORT USING @partner_num;
...
Рейтинг: 0 / 0
08.10.2013, 10:41:44
    #38419833
Cygapb-007
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объединение трёх таблиц с условием
...
Рейтинг: 0 / 0
08.10.2013, 11:02:45
    #38419873
Странник61
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объединение трёх таблиц с условием
Cygapb-007 http://sqlfiddle.com/#!2/c4e7c/8
Спасибо. Так работает.
Надеялся, что можно проще, но похоже придётся взять такой вариант.
...
Рейтинг: 0 / 0
08.10.2013, 11:12:27
    #38419882
hallabud
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объединение трёх таблиц с условием
Странник61В вашем примере ORDER BY ph.sort_phone и ASC, и DESC выдают одинаковый результат
Нет, в моем примере ASC и DESC выдают разные результаты. Вы туда зачем-то GROUP BY добавили.
...
Рейтинг: 0 / 0
08.10.2013, 11:22:21
    #38419903
Cygapb-007
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объединение трёх таблиц с условием
там при копировании ошибка вкралась:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
select 
  r.id rid, r.title rtitle
  ,p.id pid,p.partner_id ppartner_id, p.title ptitle, p.sort psort
  ,n.id nid,n.person_id nperson_id,n.value nvalue, n.sort_phone nsort_phone
from partner r
left join (
  select 
    @pn:=if(@rid=p.partner_id,@pn+1,1) pn
    ,p.id
    ,@rid:=p.partner_id partner_id
    ,p.title
    ,p.sort
  from person p,(select @rid:=0,@pn:=0)pn
  order by p.partner_id,p.sort
  )p on p.partner_id=r.id and p.pn=1
left join (
  select 
    @nn:=if(@nid=n.person_id,@nn+1,1) nn
    ,n.id
    ,@nid:=n.person_id person_id
    ,n.value
    ,n.sort_phone
  from phone n,(select @nid:=0,@nn:=0)nn
  order by n.person_id,n.sort_phone
  )n on n.person_id=p.id and n.nn=1
;

Вообще, может можно и проще, в FAQ например :)

Просто мне было интересно попробовать сделать аналог MSSQL
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
select *
from partner r
left join(
  select top(1) with ties *
  from person p
  order by row_number()over(partition by p.partner_id order by p.sort)
  ) p on p.partner_id=r.id
left join(
  select top(1) with ties *
  from phone n
  order by row_number()over(partition by p.person_id order by p.sort_phone)
  ) n on n.person_id=p.id
...
Рейтинг: 0 / 0
08.10.2013, 14:09:19
    #38420280
Странник61
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объединение трёх таблиц с условием
hallabudСтранник61В вашем примере ORDER BY ph.sort_phone и ASC, и DESC выдают одинаковый результат
Нет, в моем примере ASC и DESC выдают разные результаты. Вы туда зачем-то GROUP BY добавили.
Я думал обойтись без вычисления LIMIT,поэтому пытался добавить GROUP BY.
Но в вашем запросе всё равно всё работает только если sort_phone уникальны для персоны и не уникальны для разным персон.
У меня sort_phone уникальны в целом, примерно как id, поэтому сортировка по ним не работает.
В вашем примере я поменят значения в phone.
CREATE TABLE IF NOT EXISTS partner (id int PRIMARY KEY, title varchar(50));
CREATE TABLE IF NOT EXISTS person (id int PRIMARY KEY, partner_id int, title varchar(50), sort int);
CREATE TABLE IF NOT EXISTS phone (id int PRIMARY KEY, person_id int, value varchar(50), sort_phone int);

INSERT INTO partner VALUES
(1, 'Гугл инкорпорейтед'),
(2, 'Майкрософт'),
(3, 'Эпл компутерс');

INSERT INTO person VALUES
(1, 1, 'Сергей Брин', 1),
(2, 1, 'Ларри Пейдж', 2),
(3, 2, 'Билл Гейтс', 1),
(4, 2, 'Стив Балмер', 2),
(5, 3, 'Стив Джобс', 1),
(6, 3, 'Стив Возняк', 2);

INSERT INTO phone VALUES
(1, 1, '911', 1),
(2, 1, '102', 2),
(3, 2, '02', 5),
(4, 2, '03', 6),
(5, 3, '04', 10),
(6, 3, '09', 9),
(7, 4, '101', 7),
(8, 4, '111', 8),
(9, 5, '104', 3),
(10, 5, '112', 4),
(11, 6, '996', 11),
(12, 6, '454', 12);


SET @partner_num=(SELECT COUNT(*) FROM partner);
PREPARE GET_PARTNERS_WITH_MIN_SORT FROM
'
SELECT par.*, per.*, ph.*
FROM person per
JOIN partner par ON per.partner_id = par.id
JOIN phone ph ON per.id = ph.person_id
ORDER BY per.sort, ph.sort_phone, par.title
LIMIT ?;
';
EXECUTE GET_PARTNERS_WITH_MIN_SORT USING @partner_num;

DROP TABLE IF EXISTS partner;
DROP TABLE IF EXISTS person;
DROP TABLE IF EXISTS phone;
...
Рейтинг: 0 / 0
08.10.2013, 16:14:36
    #38420556
hallabud
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объединение трёх таблиц с условием
Cygapb-007Просто мне было интересно попробовать сделать аналог MSSQL
В MS SQL с оконными функциями вообще песня
...
Рейтинг: 0 / 0
08.10.2013, 16:59:52
    #38420636
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объединение трёх таблиц с условием
для затравочки...
Код: sql
1.
2.
3.
4.
5.
select pa.id, substring_index(min(concat_ws(',', pe.sort, ph.sort_phone, pe.id, ph.id)), ',', -2)
from partner pa, person pe, phone ph
where pa.id = pe.partner_id
and pe.id = ph.person_id
group by pa.id
...
Рейтинг: 0 / 0
08.10.2013, 22:27:31
    #38420920
Странник61
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объединение трёх таблиц с условием
Что-то у меня какой-то бред получается при подстановке.
...
Рейтинг: 0 / 0
09.10.2013, 10:47:55
    #38421186
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объединение трёх таблиц с условием
При подстановке чего именно и куда именно?
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Объединение трёх таблиц с условием / 15 сообщений из 15, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]