Запрос из двух и более таблиц

MySQL/PostgreSQL/SQLite/Oracle/M$SQL/....

Модератор: terminus

Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
Аватара пользователя
zar0ku1
сержант
Сообщения: 238
Зарегистрирован: 2008-02-29 4:38:05
Откуда: Южно-Сахалинск
Контактная информация:

Запрос из двух и более таблиц

Непрочитанное сообщение zar0ku1 » 2008-12-24 9:01:21

Дано: mysql 5.0, есть база данных в которой одинаковые таблицы по своей структуре, но с разными данными. Структуру таблиц менять нельзя.
Чтобы было проще есть 3 магазина, в них привозят товары, структура таблицы

Код: Выделить всё

|_id_|__date____|type_|_count_|
|__1_|2008-12-24|_phone|_3____|
|__2_|2008-12-24|_phone|_4____|
На каждый магазин своя таблица, то есть допустим в один день привезли телефоны 5 и 4 штуки. Нужно вывести сколько телефонов всего привезли.

При запросе:

Код: Выделить всё

$query="SELECT `date`, SUM(count) AS `count` FROM `mag1` WHERE `date` LIKE '2008-12-%' and `type`='phone' GROUP BY `date` UNION SELECT `date`, SUM(count) AS `count` FROM `mag2` WHERE `date` LIKE '2008-12-%' and `type`='phone' GROUP BY `date` ORDER BY `date` ASC;
выводит следующее:

Код: Выделить всё

2008-12-21 	164
2008-12-21 	110
2008-12-22 	213
2008-12-22 	239
2008-12-23 	222
2008-12-23 	311
2008-12-24 	214
2008-12-24 	134
А мне нужно чтобы выводило следующее:

Код: Выделить всё

2008-12-21 	274
2008-12-22 	452
2008-12-23 	533
2008-12-24 	348
Последний раз редактировалось zar0ku1 2008-12-24 9:37:49, всего редактировалось 1 раз.
На фоне дураков четче хорошие люди прорисовываются.
(с) Граффити

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

Аватара пользователя
hizel
дядя поня
Сообщения: 9032
Зарегистрирован: 2007-06-29 10:05:02
Откуда: Выборг

Re: Запрос из двух и более таблиц

Непрочитанное сообщение hizel » 2008-12-24 9:22:20

Код: Выделить всё

(SELECT `date`, SUM(count) AS `count` FROM `mag1` WHERE `date` LIKE '2008-12-%' and `type`='phone')  
UNION 
(SELECT `date`, SUM(count) AS `count` FROM `mag2` WHERE `date` LIKE '2008-12-%' and `type`='phone')
GROUP BY `date` ORDER BY `date` ASC;";
нет?
В дурацкие игры он не играет. Он просто жуткий, чу-чу, паровозик, и зовут его Блейн. Блейн --- это Боль.

Аватара пользователя
zar0ku1
сержант
Сообщения: 238
Зарегистрирован: 2008-02-29 4:38:05
Откуда: Южно-Сахалинск
Контактная информация:

Re: Запрос из двух и более таблиц

Непрочитанное сообщение zar0ku1 » 2008-12-24 9:36:49

hizel писал(а):

Код: Выделить всё

(SELECT `date`, SUM(count) AS `count` FROM `mag1` WHERE `date` LIKE '2008-12-%' and `type`='phone')  
UNION 
(SELECT `date`, SUM(count) AS `count` FROM `mag2` WHERE `date` LIKE '2008-12-%' and `type`='phone')
GROUP BY `date` ORDER BY `date` ASC;";
нет?
Пробовал

Код: Выделить всё

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'GROUP BY `date` ORDER BY `date` ASC' at line 7
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'GROUP BY `date` ORDER BY `date` ASC' at line 7
На фоне дураков четче хорошие люди прорисовываются.
(с) Граффити

Аватара пользователя
hizel
дядя поня
Сообщения: 9032
Зарегистрирован: 2007-06-29 10:05:02
Откуда: Выборг

Re: Запрос из двух и более таблиц

Непрочитанное сообщение hizel » 2008-12-24 10:34:17

при моем знании sql в башку приходят только временная таблица :(
В дурацкие игры он не играет. Он просто жуткий, чу-чу, паровозик, и зовут его Блейн. Блейн --- это Боль.

Аватара пользователя
zar0ku1
сержант
Сообщения: 238
Зарегистрирован: 2008-02-29 4:38:05
Откуда: Южно-Сахалинск
Контактная информация:

Re: Запрос из двух и более таблиц

Непрочитанное сообщение zar0ku1 » 2008-12-24 11:01:42

hizel писал(а):при моем знании sql в башку приходят только временная таблица :(
при моем тоже, но я знаю, что такие вещи в мускуле реализованны 100%, просто я их не знаю
На фоне дураков четче хорошие люди прорисовываются.
(с) Граффити

Аватара пользователя
ProFTP
подполковник
Сообщения: 3388
Зарегистрирован: 2008-04-13 1:50:04
Откуда: %&й
Контактная информация:

Re: Запрос из двух и более таблиц

Непрочитанное сообщение ProFTP » 2008-12-24 11:07:50

Код: Выделить всё

SELECT `date`,
             SUM(count) AS `count`, 
            (SELECT SUM(count) FROM `mag2` WHERE `date` LIKE '2008-12-%' and `type`='phone' GROUP BY `date` ORDER BY `date` ASC)  AS `count2`,
            (SELECT `date` FROM `mag2` WHERE `date` LIKE '2008-12-%' and `type`='phone' GROUP BY `date` ORDER BY `date` ASC)  AS  `date`
FROM `mag1` 
WHERE `date` 
LIKE '2008-12-%' and `type`='phone'
GROUP BY `date` 
ORDER BY `date` ASC;";
поробуй прмиерно так вложенный, это тоже самое что и второй, только Сишное быстродействие

PS SUM(count) AS `count` у тебя два одинакоых значение выдаються... странно... AS `count2`
Pеrl FAQ
perl -e 'print join"",map $$_[rand@$_],([0..9,'a'..'z','A'..'Z'])x30'
ИзображениеИзображение

Аватара пользователя
zar0ku1
сержант
Сообщения: 238
Зарегистрирован: 2008-02-29 4:38:05
Откуда: Южно-Сахалинск
Контактная информация:

Re: Запрос из двух и более таблиц

Непрочитанное сообщение zar0ku1 » 2008-12-24 11:31:18

ProFTP писал(а):

Код: Выделить всё

SELECT `date`,
             SUM(count) AS `count`, 
            (SELECT SUM(count) FROM `mag2` WHERE `date` LIKE '2008-12-%' and `type`='phone' GROUP BY `date` ORDER BY `date` ASC)  AS `count2`,
            (SELECT `date` FROM `mag2` WHERE `date` LIKE '2008-12-%' and `type`='phone' GROUP BY `date` ORDER BY `date` ASC)  AS  `date`
FROM `mag1` 
WHERE `date` 
LIKE '2008-12-%' and `type`='phone'
GROUP BY `date` 
ORDER BY `date` ASC;";
поробуй прмиерно так вложенный, это тоже самое что и второй, только Сишное быстродействие

PS SUM(count) AS `count` у тебя два одинакоых значение выдаються... странно... AS `count2`
Не работает, опять ошибку синтаксиса пишет... не понял про ПС
На фоне дураков четче хорошие люди прорисовываются.
(с) Граффити

Аватара пользователя
ProFTP
подполковник
Сообщения: 3388
Зарегистрирован: 2008-04-13 1:50:04
Откуда: %&й
Контактная информация:

Re: Запрос из двух и более таблиц

Непрочитанное сообщение ProFTP » 2008-12-24 11:40:03

zar0ku1 писал(а):
ProFTP писал(а):

Код: Выделить всё

SELECT `date`,
             SUM(count) AS `count`, 
            (SELECT SUM(count) FROM `mag2` WHERE `date` LIKE '2008-12-%' and `type`='phone' GROUP BY `date` ORDER BY `date` ASC)  AS `count2`,
            (SELECT `date` FROM `mag2` WHERE `date` LIKE '2008-12-%' and `type`='phone' GROUP BY `date` ORDER BY `date` ASC)  AS  `date`
FROM `mag1` 
WHERE `date` 
LIKE '2008-12-%' and `type`='phone'
GROUP BY `date` 
ORDER BY `date` ASC;";
поробуй прмиерно так вложенный, это тоже самое что и второй, только Сишное быстродействие

PS SUM(count) AS `count` у тебя два одинакоых значение выдаються... странно... AS `count2`
Не работает, опять ошибку синтаксиса пишет... не понял про ПС
меня такой таблицы нету, проверить не могу
у меня такие примерно запросы бывают часто...
Pеrl FAQ
perl -e 'print join"",map $$_[rand@$_],([0..9,'a'..'z','A'..'Z'])x30'
ИзображениеИзображение

Аватара пользователя
zar0ku1
сержант
Сообщения: 238
Зарегистрирован: 2008-02-29 4:38:05
Откуда: Южно-Сахалинск
Контактная информация:

Re: Запрос из двух и более таблиц

Непрочитанное сообщение zar0ku1 » 2008-12-24 12:01:18

ProFTP писал(а): меня такой таблицы нету, проверить не могу
у меня такие примерно запросы бывают часто...
Так чуть подправил, теперь выдает

Код: Выделить всё

subquery returns more than 1 row
ну он то как раз и должен выдавать больше, чем одну строку, что ему не нравится

А если задаю конкретную дату
то результатом является

Код: Выделить всё

date, count, count1, date1

P.S. если делать временную таблицу то:

Код: Выделить всё

mysql> CREATE TABLE tmp SELECT * FROM magazine1 UNION SELECT * FROM magazine2;
Query OK, 1356150 rows affected (3 min 29.16 sec)
Records: 1356150  Duplicates: 0  Warnings: 0
На фоне дураков четче хорошие люди прорисовываются.
(с) Граффити

MAK
ст. сержант
Сообщения: 344
Зарегистрирован: 2008-09-17 2:23:21

Re: Запрос из двух и более таблиц

Непрочитанное сообщение MAK » 2008-12-25 13:56:28

`date` LIKE '2008-12-%'
вот енто конечно мощщно. )
Вам необходимо посетить эту страничку http://dev.mysql.com/doc/refman/5.1/en/ ... types.html

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

Аватара пользователя
Alex Keda
стреляли...
Сообщения: 35420
Зарегистрирован: 2004-10-18 14:25:19
Откуда: Made in USSR
Контактная информация:

Re: Запрос из двух и более таблиц

Непрочитанное сообщение Alex Keda » 2008-12-25 14:15:39

нормальный запрос.
у меня до сих пор в коде что писал года 4 назад такие юзаются.
и ничё - народ юзает и не жалуется
Убей их всех! Бог потом рассортирует...

zg
полковник
Сообщения: 5845
Зарегистрирован: 2007-12-07 13:51:33
Откуда: Верх-Нейвинск

Re: Запрос из двух и более таблиц

Непрочитанное сообщение zg » 2008-12-25 22:08:59

задача легко просто и главное быстро решается путём создания временной таблицы

Код: Выделить всё

create temporary table t(
`date` date not null,
`count` int(1) unsigned not null,
primary key (`date`)) type=heap
а дальше тупо

Код: Выделить всё

insert into t select `date`, sum(`count`) from `table` where `date` between '2008-12-01' and '2008-12-31' and `type` = 'phone' group by `date` on duplicate update `t`.`count`=`t`.`count` + `table`.`count`
и так по всем таблицам. А после делай выборку из временной таблицы того, чего тебе надо и как надо.

Код: Выделить всё

select * from `t` order by `date` asc
Это самый быстрый и экономичный вариант.

Аватара пользователя
zar0ku1
сержант
Сообщения: 238
Зарегистрирован: 2008-02-29 4:38:05
Откуда: Южно-Сахалинск
Контактная информация:

Re: Запрос из двух и более таблиц

Непрочитанное сообщение zar0ku1 » 2008-12-26 11:35:54

Одним запросом можно реализовать так:

Код: Выделить всё

$query =SELECT `date`, SUM(count) as `count` FROM (SELECT `date`, `count` FROM mag1 UNION ALL SELECT `date`, `count` FROM mag2)  as `count` WHERE `date` LIKE '2008-12-%' GROUP BY `date`;
Всем спасибо за участие, ZG отдельно :good:
На фоне дураков четче хорошие люди прорисовываются.
(с) Граффити

zg
полковник
Сообщения: 5845
Зарегистрирован: 2007-12-07 13:51:33
Откуда: Верх-Нейвинск

Re: Запрос из двух и более таблиц

Непрочитанное сообщение zg » 2008-12-26 12:46:19

при таком запросе временная таблица тоже создаётся, возможно типа исам. Временный тип heap размещается в оперативной памяти, не использует некоторые проверки и работает исключительно быстро. По-сути мускул выполняет все описанные мной действия, только автоматом, но на это тратися дополнительное время, а иногда логика действий нарушается, что ведёт к весьма существенному увеличению времени выполнения.

В общем, прежде чем использовать тот или иной вариант иногда бывает полезным потеститься на большой базе. Ну и про explain не забывать :smile:

Кстати покажи чего выдаёт

Код: Выделить всё

EXPLAIN SELECT `date`, SUM(count) as `count` FROM (SELECT `date`, `count` FROM mag1 UNION ALL SELECT `date`, `count` FROM mag2)  as `count` WHERE `date` LIKE '2008-12-%' GROUP BY `date`

Аватара пользователя
zar0ku1
сержант
Сообщения: 238
Зарегистрирован: 2008-02-29 4:38:05
Откуда: Южно-Сахалинск
Контактная информация:

Re: Запрос из двух и более таблиц

Непрочитанное сообщение zar0ku1 » 2008-12-26 13:10:40

zg писал(а):при таком запросе временная таблица тоже создаётся, возможно типа исам. Временный тип heap размещается в оперативной памяти, не использует некоторые проверки и работает исключительно быстро. По-сути мускул выполняет все описанные мной действия, только автоматом, но на это тратися дополнительное время, а иногда логика действий нарушается, что ведёт к весьма существенному увеличению времени выполнения.

В общем, прежде чем использовать тот или иной вариант иногда бывает полезным потеститься на большой базе. Ну и про explain не забывать :smile:

Кстати покажи чего выдаёт

Код: Выделить всё

EXPLAIN SELECT `date`, SUM(count) as `count` FROM (SELECT `date`, `count` FROM mag1 UNION ALL SELECT `date`, `count` FROM mag2)  as `count` WHERE `date` LIKE '2008-12-%' GROUP BY `date`
Ну база не сильно большая 300-400мб, строк 1,5-2 миллиона, но запросы по 20с и более просто напрягают :cry:
На фоне дураков четче хорошие люди прорисовываются.
(с) Граффити

zg
полковник
Сообщения: 5845
Зарегистрирован: 2007-12-07 13:51:33
Откуда: Верх-Нейвинск

Re: Запрос из двух и более таблиц

Непрочитанное сообщение zg » 2008-12-26 13:31:15

zar0ku1 писал(а):Ну база не сильно большая 300-400мб, строк 1,5-2 миллиона, но запросы по 20с и более просто напрягают

Код: Выделить всё

stat# du -d1 -h /usr/local/mysql/data | grep /billing
190M    /usr/local/mysql/data/billing
stat#
на одну страницу бывает по 8-10 запросов, страница генерится в пределах десятых долей секунды :roll: всё строю на временных таблицах heap и правильных индексах :smile:

Аватара пользователя
zar0ku1
сержант
Сообщения: 238
Зарегистрирован: 2008-02-29 4:38:05
Откуда: Южно-Сахалинск
Контактная информация:

Re: Запрос из двух и более таблиц

Непрочитанное сообщение zar0ku1 » 2008-12-26 13:57:37

zg писал(а):
zar0ku1 писал(а):Ну база не сильно большая 300-400мб, строк 1,5-2 миллиона, но запросы по 20с и более просто напрягают

Код: Выделить всё

stat# du -d1 -h /usr/local/mysql/data | grep /billing
190M    /usr/local/mysql/data/billing
stat#
на одну страницу бывает по 8-10 запросов, страница генерится в пределах десятых долей секунды :roll: всё строю на временных таблицах heap и правильных индексах :smile:
Интересно все! Написал в личку :smile:
На фоне дураков четче хорошие люди прорисовываются.
(с) Граффити

Аватара пользователя
buryanov
ст. сержант
Сообщения: 311
Зарегистрирован: 2008-04-29 13:41:48
Откуда: Харьков
Контактная информация:

Re: Запрос из двух и более таблиц

Непрочитанное сообщение buryanov » 2008-12-28 9:08:27

а если попробовать так

Код: Выделить всё

select x.date,sum(x.M) from (
(SELECT date, SUM(count) AS count FROM mag1 WHERE date LIKE '2008-12-%' and type=phone) 
UNION
(SELECT date, SUM(count) AS count FROM mag2 WHERE date LIKE '2008-12-%' and type=phone) ) x
GROUP BY x.date ORDER BY x.date";
у меня приблизительно так считается тряфик с запросом из 3 таблиц и одновременно по разным поля(входяший и исходящий)
Дмитрий.
buryanov*ukr.net
icq# 118639660; skype: buryanov

Аватара пользователя
zar0ku1
сержант
Сообщения: 238
Зарегистрирован: 2008-02-29 4:38:05
Откуда: Южно-Сахалинск
Контактная информация:

Re: Запрос из двух и более таблиц

Непрочитанное сообщение zar0ku1 » 2008-12-28 9:10:49

buryanov писал(а):а если попробовать так

Код: Выделить всё

select x.date,sum(x.M) from (
(SELECT date, SUM(count) AS count FROM mag1 WHERE date LIKE '2008-12-%' and type=phone) 
UNION
(SELECT date, SUM(count) AS count FROM mag2 WHERE date LIKE '2008-12-%' and type=phone) ) x
GROUP BY x.date ORDER BY x.date";
у меня приблизительно так считается тряфик с запросом из 3 таблиц и одновременно по разным поля(входяший и исходящий)
вопрос уже решен, примеры решения написанны выше как с одним запросом, так и с временными таблицами
На фоне дураков четче хорошие люди прорисовываются.
(с) Граффити