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

Форум MySQL

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

 

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

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

тема: Выборка
 
 автор: nicolaus2   (11.07.2010 в 19:44)   письмо автору
 
 

Здравствуйте, форумчане! Нужна помощь.

Есть база для хранения информации об оплате пользователями неких услуг.

Таблицы:

Years
-Year //год

Months
-id // ид месяца
-name // название месяца

Dates // тут уже связки типа год + мясяц
-id //ид даты
-yearID // год
-monthID // ид месяца

Users
-id // ид
-name // имя
-ip // ип
-mac // мак
-haveToPay // сколько должен платить

main
-userID // ид пользователя
-dateID // ид даты
-payed // сколько заплатил в некий месяц некого года


Нужно сделать выборку типа, хоть так:
Имя пользователя |янв|фев|мар|апр|май|июн|июл|авг|сен|окт|ноя|дек|
Вася |10 |10 |10 |10 |10 |10 |10 |10 |10 |10 |10 |10 |
Петя |30 |30 |30 |30 |30 |30 |30 |30 |30 |30 |30 |30 |

Тоесть сколько пользователь оплатил, статистика по месяцам определенного года.

Вот вариант, которым можно получить такую статистику, за нормальное время до, 6 месяцев(тут - 4), если больше, то работает очень медленно

select users.name, Jan.payed, Feb.payed, Mar.payed, Apr.payed from users
inner join main Jan on USERs.id = Jan.`userID`
inner join main Feb on USERs.id = Feb.`userID`
inner join main Mar on USERs.id = Mar.`userID`
inner join main Apr on USERs.id = Apr.`userID`
inner join dates date1 on (Jan.`dateID` = date1.`id` and date1.`monthID` = 1 and date1.`yearID` = 2009)
inner join dates date2 on (Feb.`dateID` = date2.`id` and date2.`monthID` = 2 and date2.`yearID` = 2009)
inner join dates date3 on (Mar.`dateID` = date3.`id` and date3.`monthID` = 3 and date3.`yearID` = 2009)
inner join dates date4 on (Apr.`dateID` = date4.`id` and date4.`monthID` = 4 and date4.`yearID` = 2009)

http://ib1.keep4u.ru/b/2010/07/11/b3/b37549a4da2d3a2908a0c837d4a117fa.jpg

Нужно получить такую выборку за сносное время. Спасибо


Таблицы
create database Users

create table Years
(
    Year numeric(4,0) primary key not null
)

create table Months
(
    id numeric(2,0) primary key not NULL,
    name varchar(20) not null
)

create table Dates
(
    id numeric(5,0) primary key not NULL,
    yearID NUMERIC(4,0) REFERENCES Years(year),
    monthID numeric(2,0) references months(id)
)

create table Users
(
    id numeric(5,0) primary key not NULL,
    name varchar(50) not null, 
    ip varchar(20) not null,
    mac varchar(20) not NULL,
    haveToPay numeric(2,0) not null
)

create table main
(
    userID numeric(5,0) references Users(ID),
    dateID numeric(5,0) references Dates(ID),
    payed numeric(4,0)
)

  Ответить  
 
 автор: sms-send   (11.07.2010 в 22:34)   письмо автору
 
   для: nicolaus2   (11.07.2010 в 19:44)
 

С хранением дат, думаю, перебор.
Какие причины на такие извращения? Ведь в большинстве СУБД есть тип для хранения даты (в MySQL - это DATE).

Формирование таблицы в человекочитабельном виде - задача для обрабатывающего сценария, а не для запроса. Запрос должен заниматься выборкой, а не форматированием вывода.

Таблицы Years, Months, Dates удалить.
main.dateID удалить совсем или переименовать в date, присвоить тип даты.
Добавить целочисленное поле main.month для хранения номера месяца. Этот номер можно рассчитывать, например, так: EXTRACT(YEAR_MONTH FROM "2010-07-11").
В таблице main поставить составной индекс на поля (userID, month).
Запрос будет такой:

SELECT Users.id, Users.name, main.month, main.payed
FROM
    Users INNER JOIN main
        ON Users.id=main.userID
ORDER BY main.userID, main.month


В приложении уже извлекать результаты запроса и формировать таблицу.

  Ответить  
 
 автор: nicolaus2   (12.07.2010 в 23:11)   письмо автору
9.4 Кб
 
   для: sms-send   (11.07.2010 в 22:34)
 

Самый дельный совет из всех форумов! Спасибо!


Теперь стал более осведомлен в этом вопросе)

Решилось так(удалил дурные таблицы, в main вместо dateID - номер месяца и номер года):

CREATE TABLE `main` (
  `userID` DECIMAL(5,0) primary key not NULL,
  `months` DECIMAL(5,0),
  `years` DECIMAL(5,0),
  `payed` DECIMAL(4,0)
)

CREATE TABLE `users` (
  `id` DECIMAL(5,0) NOT NULL references Users(ID),
  `name` VARCHAR(50) NOT NULL DEFAULT '',
  `ip` VARCHAR(20) NOT NULL DEFAULT '',
  `mac` VARCHAR(20) NOT NULL DEFAULT '',
  `haveToPay` DECIMAL(2,0) NOT NULL,
  PRIMARY KEY (`id`)
)


Выборка:

SELECT Users.id, Users.name, main.months, main.payed 
FROM 
    Users INNER JOIN main 
        ON Users.id=main.userID 
        where main.years = нужный год
ORDER BY main.userID, main.months



Обработка на клиенте:

    $counter = 0;
    
    echo "<table border = 1>";
    while($row=mysql_fetch_assoc($result))
     {
         if($counter == 12)
         {
             $counter = 0;
             echo "</tr>";
         }
         if($counter == 0)
         {
             echo "<tr>";
             echo "<td>";
             echo $row["name"];
             echo "</td>";
         }
         echo "<td>";
        echo $row["payed"];
        echo "</td>";
        
        $counter++;
    };
echo "</table>";


http://ib1.keep4u.ru/b/2010/07/13/86/861018567b183d0b191db5cc92157bda.jpg

Спасибо!

  Ответить  
 
 автор: Trianon   (12.07.2010 в 23:50)   письмо автору
 
   для: nicolaus2   (12.07.2010 в 23:11)
 

и все же применять тип decimal для хранения ключевых данных
(да и вообще, в ситуации когда число цифр после точки равно нулю)
это несколько против традиций

  Ответить  
 
 автор: nicolaus2   (13.07.2010 в 01:41)   письмо автору
 
   для: Trianon   (12.07.2010 в 23:50)
 

Странно, при создании таблицы указывал тип numeric, этот код скопировал на вкладке DDL клиента EMS MYSQL

  Ответить  
 
 автор: Trianon   (13.07.2010 в 01:59)   письмо автору
 
   для: nicolaus2   (13.07.2010 в 01:41)
 

хрен редьки не слаще.
Int то чем не устраивает?

  Ответить  
Rambler's Top100
вверх

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