Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Подставить вместо значений из одной таблицы значения из др.
 
 автор: Евгений Петров   (02.10.2005 в 01:19)   письмо автору
 
 

У меня в одной таблице (counter) есть записи, например такие:
+---------+
| country |
+---------+
|   RU    |
|   UA    |
|   LT    |
+---------+

А в другой соответствие условных обозначений стран их реальным названиям
+------+--------------------+
| code |      country       |
+------+--------------------+
|  RU  | Russian Federation |
|  UA  | Ukraine            |
|  LT  | Lithuania          |
+------+--------------------+

Мне надо выполнить запрос который бы показывал с каких стран заходят посетители и сколько таких посетителей. Я делаю:
code[SELECT country,COUNT(country) FROM counter GROUP BY country[/code]
Но вся беда в том что этот запрос выведет условные обозначения стран, а мне надо сделать так чтобы вместо них были их реальные названия. Как это можно сделать? Спасибо!

   
 
 автор: cheops   (02.10.2005 в 01:23)   письмо автору
 
   для: Евгений Петров   (02.10.2005 в 01:19)
 

Следует осуществить многотабличный запрос
SELECT tbl.country AS country, COUNT(counter.country) AS total 
FROM counter, tbl
WHERE counter.country = tbl.code
GROUP BY counter.country

где tbl - имя второй таблицы с полными именами стран.

   
 
 автор: Евгений Петров   (02.10.2005 в 01:31)   письмо автору
 
   для: cheops   (02.10.2005 в 01:23)
 

Спаибо! То что надо.

   
 
 автор: Евгений Петров   (02.10.2005 в 01:35)   письмо автору
 
   для: Евгений Петров   (02.10.2005 в 01:31)
 

А нет не совсем то COUNT() выдает не количество посетителей в таблице counter а количество стран в таблице tbl (точнее ip :) ), т.е. если например в таблице ip будут две одинаковые записи:
+------+---------+
| code | country |
+------+---------+
|  UA  | Ukraine |
|  UA  | Ukraine |
+------+---------+

То COUNT выведет 2

   
 
 автор: cheops   (02.10.2005 в 13:53)   письмо автору
 
   для: Евгений Петров   (02.10.2005 в 01:35)
 

Так а какие поля содержит таблица counter и что нужно? :))) У меня-то перед глазами только одно поле из этой таблицы, я даже не знаю какие данные в ней храняться...

   
 
 автор: Евгений Петров   (02.10.2005 в 19:13)   письмо автору
 
   для: cheops   (02.10.2005 в 13:53)
 

А больше и не надо. Просто когда пользователь заходит на страницу в таблицу counter заносится страна в которой он находится в виде RU. А в таблице ip находятся соответствия этих стран (их коротких названий) их реальным названиям (Rusian Federation). Так вот мне надо узнать из каких стран заходят пользователи на основе таблицы counter, но страны должны віводится не RU а Rusian Federation (на основе таблицы ip)

   
 
 автор: Евгений Петров   (03.10.2005 в 16:40)   письмо автору
 
   для: Евгений Петров   (02.10.2005 в 19:13)
 

-

   
 
 автор: Евгений Петров   (03.10.2005 в 16:40)   письмо автору
 
   для: Евгений Петров   (02.10.2005 в 19:13)
 

Т.е. вот например таблицы
  counter                 ip

+---------+  +------+--------------------+
| country |  | code |       country      | 
+---------+  +------+--------------------+
|   RU    |  |  RU  | Russian Federation |
|   RU    |  |  BY  | Belarus            |
|   RU    |  |  UA  | Ukraine            |
|   BY    |  |  LT  | Lithuania          |
|   RU    |  |  KZ  | Kazakstan          |
|   UA    |  |  GE  | Georgia            |
|   RU    |  |  JP  | Japan              |
|   RU    |  |  DE  | Germany            |
|   RU    |  |  CY  | Cyprus             |
|   UA    |  +------+--------------------+
|   LT    |
|   RU    |
|   KZ    |  
|   RU    |
|   RU    |
|   RU    |
|   GE    |
|   UA    |
|   JP    |
|   DE    |
|   DE    |
|   RU    |
|   RU    |
|   RU    |
|   CY    |
+---------+


Заgрос:
SELECT country,COUNT(country) FROM counter GROUP BY country

выведет:
+---------+----------------+
| country | COUNT(country) |
+---------+----------------+
|   BY    |       1        |
|   CY    |       1        |
|   DE    |       2        |
|   GE    |       1        |
|   JP    |       1        |
|   KZ    |       1        |
|   LT    |       1        |
|   RU    |       14       |
|   UA    |       3        |
+---------+----------------+

А мне надо вывести:
+--------------------+----------------+
|       country      | COUNT(country) |
+--------------------+----------------+
| Belarus            |       1        |
| Cyprus             |       1        |
| Germany            |       2        |
| Georgia            |       1        |
| Japan              |       1        |
| Kazakstan          |       1        |
| Lithuania          |       1        |
| Russian Federation |       14       |
| Ukraine            |       3        |
+--------------------+----------------+


В принципе ваш запрос:
SELECT ip.country AS country, COUNT(counter.country) AS total
FROM counter, ip
WHERE counter.country = ip.code
GROUP BY counter.country

выводит все правильно, если только в таблице ip данные не повторяются, а они повторяются. Вы легко можете увидеть что получится если добавить в таблицу ip пару записей:
INSERT INTO ip() VALUES('CY','Cyprus');
INSERT INTO ip() VALUES('CY','Cyprus');


В аттаче дамп таблиц!

   
 
 автор: napTu3aH   (03.10.2005 в 17:46)   письмо автору
 
   для: Евгений Петров   (03.10.2005 в 16:40)
 

Вам поможет этот запрос

SELECT ip.country, 
COUNT( counter.country ) 
FROM counter, ip
WHERE ip.code = counter.country
GROUP BY counter.country


P.S. Вижу не пойдет, а как может быть у одной аббревиатуры страны 2 или 3 расшифровки?
P.P.S. Пусть будут совпадать. Но у аббр.CY всегда будет страна Cyprus? Зачем тогда держать одинаковые строки в Базе?

   
 
 автор: Евгений Петров   (03.10.2005 в 18:54)   письмо автору
 
   для: napTu3aH   (03.10.2005 в 17:46)
 

На самом деле я привел не всю структуру. В таблице ip хранятся диапазоны ip адресов и соответствие их странам. Например:
+----------+----------+------+----------------+
| ip_from  |  ip_to   | code | country        |
+----------+----------+------+----------------+
| 33996344 | 33996351 |  GB  | United Kingdom |
| 50331648 | 68257567 |  US  | United States  |
| 68257568 | 68257599 |  CA  | Canada         |
| 68257600 | 68259583 |  US  | United States  |
| 68259584 | 68259599 |  CA  | Canada         |
| 68259600 | 68296775 |  US  | United States  |
| 68296776 | 68296783 |  MX  | Mexico         |
| ........ | ........ |  ..  | .............. |
+----------+----------+------+----------------+

Поэтому страны повторяются

   
 
 автор: napTu3aH   (03.10.2005 в 19:43)   письмо автору
 
   для: Евгений Петров   (03.10.2005 в 18:54)
 

Бррррр. У вас в таблице ip адресов уже хранитсья информация о кол-ве людей из разных стран.

SELECT COUNT(code), country FROM ip GROUP BY code

Зачем тогда считать это количество в другой таблице "counter"? Или в этой таблице у вас считаютсья другие страны?

Если все-таки в таблице "counter" другие страны и кол-во нежели в "ip" вам лучше создать еще одну таблицу "strani" в которой будет только 2 поля, сокращения и их расшифровка. И используйте эту таблицу только для расшифровки. Тогда можно будет из таблицы "ip" убрать поле "country "

   
 
 автор: Евгений Петров   (03.10.2005 в 20:24)   письмо автору
 
   для: napTu3aH   (03.10.2005 в 19:43)
 

Рассказываю ещё раз. :)
У меня есть две таблицы:
Таблица №1 (counter):
В этой таблице хранится информация о посетителях. Когда я захожу на страницу где стоит счетчик при помощи моего ip адреса и таблицы ip (о ней чуть позже) узнается страна в которой я нахожусь, точнее её сокращенное обозначение (в целях экономии места). Эта страна заносится в таблицу counter.
Таблица №2 (ip):
Это база данных ip адресов. У нее 4 поля первые 2 - это диапазон адресов:
Например:
2.6.190.56-2.6.190.63

Только этот диапазон хранится в виде числа, которое получается при использовании функции INET_ATON() т.е. соответственно:
33996344-33996351

Остальные 2 поля - это сокращенное и полное название страны, к которой относится данный диапазон ip-адресов.
"GB","United Kingdom"


Так вот основываясь на данных из таблицы counter мне нужно получить информацию о том в каких странах находятся пользователи и сколько таких пользователей в каждой стране.

   
 
 автор: napTu3aH   (03.10.2005 в 20:36)   письмо автору
 
   для: Евгений Петров   (03.10.2005 в 20:24)
 

А в таблице "ip" есть необходимость держать полные имена стран, если уже есть сокращенные?
Я бы смело убрал поле с полным именем и создал бы таблицу 3, в которой только было бы 2 поля сокращенные названия стран и их расшифровка.

Из вашего же скрипта

CREATE TABLE Strani (
  'code' char(2) NOT NULL default '',
  'country' varchar(20) NOT NULL default ''
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;

З.Ы. У меня была немного похожая ситуация с таблицами. Долго не мог решить сколько их нужно. Хеопс с Локи мне помогли разобраться и действительно, то что я сначала хотел держать в одной таблице, замечательно поделилось на 3. Да сначала была каша у меня в голове, но немного разобравшись я понял, что это то что нужно. И избавил себя от каши и путанины в БД.

   
 
 автор: Евгений Петров   (03.10.2005 в 20:42)   письмо автору
 
   для: napTu3aH   (03.10.2005 в 20:36)
 

...и создал бы таблицу 3, в которой только было бы 2 поля сокращенные названия стран и их расшифровка.
А толку? Сокращенные названия стран мне нужны для того, чтобы в таблице counter (в которой хранится ОЧЕНЬ много записей можно было хоть как то сэкономить место, т.е. писать не 20 символов а только 2). И подмену сокращенных названий на их полные соответствия мне и нужно сделать. А смысл создавать ещё одну таблицу со странами, если она уже есть?

   
 
 автор: napTu3aH   (03.10.2005 в 20:50)   письмо автору
 
   для: Евгений Петров   (03.10.2005 в 20:42)
 

Хм. Может Хеопс что-то другое посоветует. Но я бы поступил именно так.

   
 
 автор: Евгений Петров   (03.10.2005 в 20:53)   письмо автору
 
   для: napTu3aH   (03.10.2005 в 20:50)
 

Буду ждать cheops'a. :)
P.S. Кстати cheops, почему ваш ник именно cheops? Что он значит? И как правильно его произносить, потому что как только тут не писали. :)

   
 
 автор: cheops   (04.10.2005 в 01:04)   письмо автору
 
   для: Евгений Петров   (03.10.2005 в 20:53)
 

Ник мой следует произносить, как его произносит Партизан - Хеопс (Хуфу) - в честь одноименного фараона четвёртой династии - историю выбора этого ника можно почитать в теме по ссылке http://www.softtime.ru/forum/read.php?id_forum=2&id_theme=7196.

   
 
 автор: Евгений Петров   (03.10.2005 в 18:56)   письмо автору
 
   для: napTu3aH   (03.10.2005 в 17:46)
 

А запрос у вас аналогичный тому, который привел cheops и следовательно он тоже не подходит

   
 
 автор: cheops   (04.10.2005 в 01:00)   письмо автору
 
   для: Евгений Петров   (03.10.2005 в 16:40)
 

>выводит все правильно, если только в таблице ip данные не
>повторяются, а они повторяются. Вы легко можете
>увидеть что получится если добавить в таблицу ip пару
>записей:
>
INSERT INTO ip() VALUES('CY','Cyprus');
>INSERT INTO ip() VALUES('CY','Cyprus');

Странно - добавил две Cyprus - хоть бы хны - всё выводится правильно
Belarus 3 
Cyprus 1 
Germany 2 
Georgia 1 
Japan 1 
Kazakstan 1 
Lithuania 1 
Russian Federation 14 
Ukraine 3 

У вас какая версия базы данных (у меня 4.0.24).

   
 
 автор: Евгений Петров   (04.10.2005 в 01:30)   письмо автору
 
   для: cheops   (04.10.2005 в 01:00)
 

У меня тоже 4.0.24 и при добавлении ещё двух CY их количество после выполнения запроса увеличивается ровно на 2 единицы

   
 
 автор: cheops   (04.10.2005 в 13:48)   письмо автору
 
   для: Евгений Петров   (04.10.2005 в 01:30)
 

А вы бы не могли в архиве выложить бинарные файлы таблицы - т.е. развернуть приведённый выше дамп и выложить файлы таблицы, добавить туда 2 лишних CY, проверить запрос и если он не работает выложить - эти файлы:
C:/mysql/data/имя_базы_данных/имя_таблицы.frm
C:/mysql/data/имя_базы_данных/имя_таблицы.MYD
C:/mysql/data/имя_базы_данных/имя_таблицы.MYI

   
 
 автор: Евгений Петров   (04.10.2005 в 14:54)   письмо автору
 
   для: cheops   (04.10.2005 в 13:48)
 

Вот

   
 
 автор: cheops   (05.10.2005 в 00:51)   письмо автору
 
   для: Евгений Петров   (04.10.2005 в 14:54)
 

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

   
 
 автор: Евгений Петров   (05.10.2005 в 01:14)   письмо автору
 
   для: cheops   (05.10.2005 в 00:51)
 

Ну если только создать новую таблицу, что не очень хочется.
Ну или делать проще. Делать выборку:
SELECT country,COUNT(country) FROM counter GROUP BY country

А дальше в цикле искать для каждого значения кода его полное название:
SELECT country FROM ip WHERE code = '$fetch[country]' LIMIT 1

И делать подмену при помощи php. Хотя этот вариант мне тоже н нравится.

   
 
 автор: cheops   (05.10.2005 в 01:21)   письмо автору
 
   для: Евгений Петров   (05.10.2005 в 01:14)
 

Да всё равно стран не много цикл даже из 126 стран не сильно увеличит загрузку - кроме того вы избежите двух-табличного запроса, который тоже жрёт ресурсы. Вряд ли вы много потеряете в этом случае.

   
 
 автор: Евгений Петров   (05.10.2005 в 01:27)   письмо автору
 
   для: cheops   (05.10.2005 в 01:21)
 

Т.е. вы все таки предлагаете мне сделать другую таблицу?

   
 
 автор: cheops   (05.10.2005 в 13:58)   письмо автору
 
   для: Евгений Петров   (05.10.2005 в 01:27)
 

Или цикл. Кстати таблица может быть временной. Правда создание таких таблиц часто запрещается на хостингах и может серьёзно снизить производительность при частом обращении к скрипту.

   
 
 автор: Евгений Петров   (05.10.2005 в 16:56)   письмо автору
 
   для: cheops   (05.10.2005 в 13:58)
 

А чем можно заменить временные таблицы?

   
 
 автор: cheops   (06.10.2005 в 00:32)   письмо автору
 
   для: Евгений Петров   (05.10.2005 в 16:56)
 

Постоянной таблицей :))) Тем более у вас наверное не часто будет обновлятся таблица ip...

   
 
 автор: Евгений Петров   (06.10.2005 в 00:39)   письмо автору
 
   для: cheops   (06.10.2005 в 00:32)
 

А если мне надо создать временную таблицу для определенного пользователя? Т.е. я запускаю скрипт и он создает временную таблицу, в это же время кто нибудь запускает этот же скрипт и он тоже создает временную таблицу. Это будет одна и та же таблица или они будут разные? Данные в них не перепутаються?

   
 
 автор: cheops   (06.10.2005 в 00:48)   письмо автору
 
   для: Евгений Петров   (06.10.2005 в 00:39)
 

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

   
 
 автор: Евгений Петров   (06.10.2005 в 00:50)   письмо автору
 
   для: cheops   (06.10.2005 в 00:48)
 

Вот поэтому я и спросил. Ведь с постоянной таблицей такое не прокатит?

   
 
 автор: cheops   (06.10.2005 в 13:17)   письмо автору
 
   для: Евгений Петров   (06.10.2005 в 00:50)
 

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

   
 
 автор: Евгений Петров   (08.10.2005 в 15:49)   письмо автору
 
   для: cheops   (06.10.2005 в 13:17)
 

Да нет страны я в постоянную таблицу засунул. Просто половина моего скрипта не будет работать без временных таблиц. Хотя это уже не проблема на том хостинге для которого пишется скрипт они поддерживаются. Спасибо!

   
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования