powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Запрос с объединением
9 сообщений из 9, страница 1 из 1
Запрос с объединением
    #33480321
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть такая таблица:

--
-- Структура таблицы `songs`
--

CREATE TABLE `songs` (
`id` int(11) NOT NULL auto_increment,
`author_id` int(11) NOT NULL default '0',
`name` varchar(255) NOT NULL default '',
`type` tinyint(4) NOT NULL default '0',
`tcid` int(11) default NULL,
`sndx` varchar(255) NOT NULL default '',
PRIMARY KEY (`id`),
KEY `author_id` (`author_id`,`type`,`tcid`),
KEY `name` (`name`),
KEY `sndx` (`author_id`,`sndx`,`id`)
) TYPE=MyISAM AUTO_INCREMENT=2130 ;

--
-- Дамп данных таблицы `songs`
--

INSERT INTO `songs` VALUES (32, 3, 'Big Gun', 1, 32, 'B250');
INSERT INTO `songs` VALUES (2053, 3, 'Big Gun', 2, 114, 'B250');
INSERT INTO `songs` VALUES (2046, 3, 'Back In Black (2)', 2, 107, 'B25142');
INSERT INTO `songs` VALUES (2047, 3, 'Back In Black (3)', 2, 108, 'B25142');
INSERT INTO `songs` VALUES (2048, 3, 'Back In Black (4)', 2, 109, 'B25142');
INSERT INTO `songs` VALUES (2049, 3, 'Back in Black', 2, 110, 'B25142');
INSERT INTO `songs` VALUES (2050, 3, 'Bad Boy Boogie', 2, 111, 'B312');
INSERT INTO `songs` VALUES (2054, 3, 'Bonny', 2, 115, 'B500');
INSERT INTO `songs` VALUES (2060, 3, 'Classic Riffs', 2, 121, 'C42612');
INSERT INTO `songs` VALUES (2063, 3, 'Dog eat dog (2)', 2, 124, 'D232');
INSERT INTO `songs` VALUES (2064, 3, 'Dog Eat Dog (3)', 2, 125, 'D232');
INSERT INTO `songs` VALUES (2065, 3, 'Dog Eat Dog', 2, 126, 'D232');
INSERT INTO `songs` VALUES (2061, 3, 'Damned', 2, 122, 'D530');
INSERT INTO `songs` VALUES (2062, 3, 'Dirty Deeds Done Dirt Cheap', 2, 123, 'D6323536321');
INSERT INTO `songs` VALUES (2066, 3, 'For Those About To Rock', 2, 127, 'F6321362');
INSERT INTO `songs` VALUES (2067, 3, 'Girls got rhythm', 2, 128, 'G6423635');
INSERT INTO `songs` VALUES (2071, 3, 'Have a drink on me (2)', 2, 132, 'H136525');
INSERT INTO `songs` VALUES (2072, 3, 'Have A Drink On Me (3)', 2, 133, 'H136525');
INSERT INTO `songs` VALUES (2073, 3, 'Have A Drink On Me', 2, 134, 'H136525');
INSERT INTO `songs` VALUES (2079, 3, 'High Voltage', 2, 140, 'H21432');
INSERT INTO `songs` VALUES (33, 3, 'Highway To Hell', 1, 33, 'H234');
INSERT INTO `songs` VALUES (2080, 3, 'Highway to Hell (2)', 2, 141, 'H234');
INSERT INTO `songs` VALUES (2081, 3, 'Highway To Hell (3)', 2, 142, 'H234');
INSERT INTO `songs` VALUES (2083, 3, 'Highway to Hell', 2, 144, 'H234');
INSERT INTO `songs` VALUES (2082, 3, 'Highway To Hell (solo)', 2, 143, 'H23424');

Здесь author_id задаёт id автора/исполнителя, type -- тип данных (табы или аккорды), tcid -- id записи этих данных, name -- название композиции.
Сразу скажу, что структура данных может быть предметом обсуждения, если вы можете предложить более оптимальный вариант. Нужно сделать запрос, возвращающий следующие данные:
Name | chords_id | tabs_id
где chords_id или tabs_id может быть нулевым, если для данного названия есть только табы или аккорды соответственно.
Я добился _почти_ этого запросом
SELECT A.name AS name, IF(A.type=1,A.tcid,NULL) AS chords_id, IF(B.type=2,B.tcid,NULL) AS tabs_id FROM songs AS A LEFT JOIN songs AS B ON A.name=B.name WHERE A.author_id=3 AND B.author_id=3 AND (A.type=1 OR B.type=2) ORDER BY name, chords_id DESC, tabs_id DESC;

но среди результатов получаются такие затроения:

| Big Gun | 32 | 114 |
| Big Gun | 32 | NULL |
| Big Gun | NULL | 114 |

и убрать их с помощью GROUP BY name не удаётся, т.к. группировка происходит до сортировки, и запись остаётся

| Big Gun | 32 | NULL |

, а не

| Big Gun | 32 | 114 |

Судя по ухищрениям, к которым приходится прибегать в запросе, я не оптимально выбрал структуру данных, но лучших вариантов в голову не приходит.(
...
Рейтинг: 0 / 0
Запрос с объединением
    #33480656
max(id)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Такое решение разве Вам не подойдет ?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
SELECT s.name AS name, 
       max(IF(s.type= 1 ,s.tcid,NULL)) AS chords_id, 
       max(IF(s.type= 2 ,s.tcid,NULL)) AS tabs_id 
FROM songs AS s 
WHERE s.author_id= 3  
  AND (s.type= 1  OR s.type= 2 )
GROUP BY s.name 
ORDER BY name, chords_id DESC, tabs_id DESC;
P.S. И хорошо бы узнать, какая у вас версия MySQL-я?
...
Рейтинг: 0 / 0
Запрос с объединением
    #33480673
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо, похоже, то что надо.
Пока не понял, как оно работает, правда.)
Насчёт MySQL следует рассчитывать только на 4.0, к сожалению...
Но оно и работает на 4.0!
...
Рейтинг: 0 / 0
Запрос с объединением
    #33482343
Фотография Dinky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а может тупо юнионом объединить пачку селектов? имхо, гораздо быстрее работать будет ;)

--
Dmitry
...
Рейтинг: 0 / 0
Запрос с объединением
    #33482619
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гм. Каких селектов?
...
Рейтинг: 0 / 0
Запрос с объединением
    #33482640
Фотография Dinky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ээ, ok, пробую прочитать еще раз :)
...
так там дубли, а-я-я-й :)
че б не провести нормализацию - выкинуть таблатуры и аккорды в отдельные таблицы, чтобы в таблице songs были только уникальные записи (песни)?

--
Dmitry
...
Рейтинг: 0 / 0
Запрос с объединением
    #33482644
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Какую структуру данных вы предлагаете?
...
Рейтинг: 0 / 0
Запрос с объединением
    #33482680
Фотография Dinky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
если честно, я не совсем понял текущую структуру, а именно - зачем в songs лежат линки на таблатуры и аккорды? может, лучше в последние положить линки на песни, ну в классическом виде:
songs: id, author_id, name, ...
tabs: id, song_id, ...
chords: id, song_id, ...
songs.id - один-ко-многим - song_id
тогда запрос будет такой:

SELECT s.id, s.name, t.id, c.id
FROM songs s LEFT JOIN tabs t ON s.id=t.song_id
LEFT JOIN chords c ON s.id=c.song_id
WHERE ...

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

--
Dmitry
...
Рейтинг: 0 / 0
Запрос с объединением
    #33482708
DocAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ага, конечно!
Спасибо. Дело в том, что первоначальная, с позволения сказать "структура базы" была вообще никакая, я провёл некоторую работу, чтобы хотя бы создать общую таблицу авторов и песен, но т.к. делалось всё не с того конца, получилась такая вот странная конструкция. А я в неё упёрся и всё удивлялся, почему через LEFT JOIN запрос переписать нормально не выходит.
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Запрос с объединением
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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