Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Выборка из 2 таблиц из нескольких строк.

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Без описания
NightElf
Отправлено: 17 Мая, 2012 - 11:59:12
Post Id


Новичок


Покинул форум
Сообщений всего: 22
Дата рег-ции: Июнь 2011  


Помог: 0 раз(а)




Добрый день. Столкнулся со следующей проблемой:

есть 2 таблички abon и uslugi. Соответственно по структуре у одного абонента, может быть несколько строк с записями о услугах (интернет, телефония, тв). Необходимо сделать выборку следующего вида: вывести количество абонентов у которых подключены телефон и телевидения на любом тарифном плане и интернет с определенным тарифным планом.

Структура таблиц:
desc abon (Отобразить)


desc uslugi (Отобразить)


Как таковой связи между таблицами нету, кроме номера договора.

Пробовал вывести вот так:

PHP:
скопировать код в буфер обмена
  1. $us1 = "Телефон";
  2. $us2 = "Телевидение";  
  3. $us3 = "Интернет";     
  4. $tp = "Тариф1";
  5. mysql_query('select count(*) from abon,uslugi where uslugi.usluga = \''.$us1.'\' and uslugi.usluga = \''.$us2.'\' and (uslugi.tp = \''.$tp.'\' and uslugi.usluga = \''.$us3.'\') and abon.dogovor = uslugi.dogovor;');
  6.  

Но так не работает, т.к., насколько я понимаю, мускл пытается найти все это в одной строке таблицы uslugi.

Возникает вопрос - как правильно составить запрос, чтобы мне выдало количество абонентов у которых подключен Телефон, Телевидение и Интернет на тарифе "Тариф1". Заранее спасибо за помощь.

(Отредактировано автором: 17 Мая, 2012 - 12:02:29)

 
 Top
CrazyOne
Отправлено: 17 Мая, 2012 - 16:17:02
Post Id


Новичок


Покинул форум
Сообщений всего: 40
Дата рег-ции: Май 2012  


Помог: 0 раз(а)




CODE (SQL):
скопировать код в буфер обмена
  1. SELECT COUNT(*) FROM abon JOIN uslugi ON abon.dogovor = uslugi.dogovor WHERE uslugi.usluga = ?

(Отредактировано автором: 17 Мая, 2012 - 16:17:34)

 
 Top
NightElf
Отправлено: 21 Мая, 2012 - 09:28:03
Post Id


Новичок


Покинул форум
Сообщений всего: 22
Дата рег-ции: Июнь 2011  


Помог: 0 раз(а)




Так работает только если указать в условии только одну услугу. При добавлении в условие второй услуги (т.е. вывести количество абонентов у которых подключена Телефония и Телевидение) - выводит 0.

CODE (htmlphp):
скопировать код в буфер обмена
  1. SELECT count(*) FROM abon JOIN uslugi ON abon.dogovor = uslugi.dogovor WHERE uslugi.usluga = 'Телефон' and uslugi.usluga = 'Телевидение';

(Отредактировано автором: 21 Мая, 2012 - 09:42:46)

 
 Top
tuareg
Отправлено: 21 Мая, 2012 - 09:43:32
Post Id


Участник


Покинул форум
Сообщений всего: 1234
Дата рег-ции: Июнь 2010  


Помог: 69 раз(а)




Вместо JOIN--> LEFT JOIN или RIGHT JOIN
 
 Top
Мелкий Супермодератор
Отправлено: 21 Мая, 2012 - 09:56:49
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




Откуда вы вообще достали imya_uslugi? У вас нет такого поля!

Джойнить по text'у! Не понял охохохо, я в печали Хм
А id у вас числовые потому что autoincrement по тексту не заработал?


-----
PostgreSQL DBA
 
 Top
NightElf
Отправлено: 21 Мая, 2012 - 10:03:40
Post Id


Новичок


Покинул форум
Сообщений всего: 22
Дата рег-ции: Июнь 2011  


Помог: 0 раз(а)




То же самое. При поиске по одному критерию работает, по 2 - выводит 0 (Empty Set.)

На всякий случай уточню: нужно вывести не просто количество человек у которых есть ТВ и телефон, а именно тех - у кого ТВ и телефон одновременно.
Т.е. например всего 1000 человек, из них у 800 подключено ТВ, у 300 телефония, а одновременно эти две услуги подключены у 100 человек. Вот число 100 мне и нужно получить.

Насколько я это понимаю выборка JOINом будет выглядеть так: для абонента с 3 услугами (инет,тлф,тв) будет выбрано 3 строки, в первой строке вся инфа из таблицы абон + инфа из 1 строки таблицы услуги(по интернету), во второй строке вся инфа из таблицы абон + инфа из 2 строки таблицы услуги и т.д. Соответственно при задании условий все равно проверяется удовлетворяет ли всем условиям одна из строк. А т.к. ни в одной строке нет сразу нескольких наименований услуг, то и выборка выдает Empty Set.

(Добавление)
Мелкий пишет:
Откуда вы вообще достали imya_uslugi? У вас нет такого поля!


Это я поправил. Запрос при копировании забыл изменить.

Мелкий пишет:
А id у вас числовые потому что autoincrement по тексту не заработал?


Наследие предыдущего программиста. Я больше по железу, но вот сейчас на php+mysql подрядили, вот и разбираю.

(Отредактировано автором: 21 Мая, 2012 - 10:21:09)

 
 Top
Zuldek
Отправлено: 21 Мая, 2012 - 10:36:07
Post Id


Постоянный участник


Покинул форум
Сообщений всего: 2122
Дата рег-ции: Июнь 2010  


Помог: 50 раз(а)




1. Если существует возможность изменения структуры таблиц бд - сделайте это.
Как минимум, - числовые внешние ключи для обоих таблиц.
2. Сделайте SELECT * FROM abon LEFT JOIN uslugi ON abon.dogovor = uslugi.dogovor ORDER BY abon.dogovor; И посмотрите смущает-ли что-то в выборке.

Учитывая, что зачем то хранятся текстовые наименования идентичных (по уму) услуг uslugi.usluga, попробуйте сразу выполнить выборку с LIKE... .

(Отредактировано автором: 21 Мая, 2012 - 10:39:48)

 
 Top
Мелкий Супермодератор
Отправлено: 21 Мая, 2012 - 10:41:40
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




NightElf пишет:
uslugi.usluga = 'Телефон' and uslugi.usluga = 'Телевидение';

Тут вас сразу парсер запроса заворачивает. Одно и то же поле не может одновременно содержать два разных значения.

CODE (SQL):
скопировать код в буфер обмена
  1. SELECT count(0) FROM (
  2.     SELECT count(0) AS cnt, dogovor FROM uslugi WHERE usluga IN ('Телефон', 'Телевидение') GROUP BY dogovor HAVING cnt=2
  3.     ) services

Если на одном договоре нет одновременно 2 телефонов, например. Иначе сработает ошибочно.


-----
PostgreSQL DBA
 
 Top
NightElf
Отправлено: 21 Мая, 2012 - 11:00:04
Post Id


Новичок


Покинул форум
Сообщений всего: 22
Дата рег-ции: Июнь 2011  


Помог: 0 раз(а)




Мелкий пишет:
Если на одном договоре нет одновременно 2 телефонов, например. Иначе сработает ошибочно.


К сожалению, у юр.лиц до 8 телефонов встречается на одном договоре. Но по физикам думаю пройдет - сейчас протестирую. Если я правильно понимаю - ошибочно сработает из-за того что указано количество строк - 2.

(Отредактировано автором: 21 Мая, 2012 - 11:01:25)

 
 Top
Мелкий Супермодератор
Отправлено: 21 Мая, 2012 - 11:17:08
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




Тогда можно вот так выкрутиться:
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT count(0) FROM (
  2.     SELECT sum(usluga='Телефон') AS `haveTel`, sum(usluga='Телевидение') AS `haveTV`, dogovor FROM uslugi WHERE usluga IN ('Телефон', 'Телевидение') GROUP BY dogovor HAVING `haveTV` AND `haveTel`
  3.     ) services


-----
PostgreSQL DBA
 
 Top
NightElf
Отправлено: 22 Мая, 2012 - 12:08:01
Post Id


Новичок


Покинул форум
Сообщений всего: 22
Дата рег-ции: Июнь 2011  


Помог: 0 раз(а)




Мелкий пишет:
Тогда можно вот так выкрутиться:
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT count(0) FROM (
  2.     SELECT sum(usluga='Телефон') AS `haveTel`, sum(usluga='Телевидение') AS `haveTV`, dogovor FROM uslugi WHERE usluga IN ('Телефон', 'Телевидение') GROUP BY dogovor HAVING `haveTV` AND `haveTel`
  3.     ) services


Выдает 0:

CODE (SQL):
скопировать код в буфер обмена
  1. mysql>  SELECT count(0) FROM (SELECT sum(usluga='Телефон') AS `haveTel`, sum(usluga='Телевидение') AS `haveTV`, dogovor FROM uslugi WHERE usluga IN ('Телефон', 'Телевидение') GROUP BY dogovor HAVING `haveTV` AND `haveTel`) uslugi;
  2. +----------+
  3. | count(0) |
  4. +----------+
  5. |        0 |
  6. +----------+
  7. 1 row IN SET, 1 warning (0.00 sec)
  8.  

Тут попробовал просто вывести табличку чтобы была вида ФИО, тп-интернета, тп-телефона, тп-телевидения. Получилось, правда возможно несколько коряво, вот код выборки:

Спойлер (Отобразить)


Однако если поставить перед echo условие вывести например только тех у кого есть Телефон и Телеидение:
PHP:
скопировать код в буфер обмена
  1. if ($tpp1 == '' AND $tpp2 != '' AND $tpp3 != '')
, то нумерация строк все равно остается от общего запроса. Т.е. первая строка имеет п/п 43, вторая 129 и т.д. Можно как то это решить? чтобы нумерация строк выводилась с учетом условия прописанного в IF, либо просто подсчитать количество выведенных строк с учетом условия?

Насколько я понимаю - самым простым вариантом является подсчитать количество строк <tr> у выведенной таблицы. Но вот как это реализовать - вопрос.

(Отредактировано автором: 22 Мая, 2012 - 12:28:05)

 
 Top
NightElf
Отправлено: 22 Мая, 2012 - 15:54:02
Post Id


Новичок


Покинул форум
Сообщений всего: 22
Дата рег-ции: Июнь 2011  


Помог: 0 раз(а)




По поводу подсчета <tr> сделал через js:
CODE (html):
скопировать код в буфер обмена
  1.  
  2. <script>var tr = document.getElementsByTagName(\'table\').item(0).getElementsByTagName(\'tr\').length; tr=tr-1; document.write(tr);</script>
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« SQL и Архитектура БД »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB