Задавайте вопросы, мы ответим
Вы не зашли.
Здравствуйте, форумчане! Нужна помощь.
Есть база для хранения информации об оплате пользователями неких услуг.
Таблицы:
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)
Нужно получить такую выборку за сносное время. Спасибо
Таблицы
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) )
Неактивен
А почему Вы дату храните не через DATE, а через такие странные связи?
Должно работать быстро при добавлении соответствующих индексов.
Соответствующий — это, видимо, Dates(month, year).
Неактивен
Знаю, было тупо.
Решилось так(удалил дурные таблицы, в 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>";
Спасибо!
Отредактированно nicolaus2 (12.07.2010 23:14:08)
Неактивен
nicolaus2 написал:
Знаю, было тупо.
Решилось так(удалил дурные таблицы, в 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)
)
Всё же что вам мешает хранить даты как даты? (`date` DATE). Если уж так хочется в разных колонках, то есть спец типы YEAR и MONTH. Кроме столбца `payed` использовать тип DECIMAL не нужно, для месяца и года подойдет и TINYINT и даже ENUM, это же целые числа (хотя все же лучше временнЫе). userId в зависимости от количества записей какой-нибудь INT, MEDIUMINT и т.п. Кстати оно у вас сейчас уникальное, а из того как я понял вашу задачу у вас в этой таблице будет по несколько записей на пользователя.
`Payed` тоже не понятно - сумма, но без копеек?
Неактивен
Всё верно говорите. Сменил numeric -> TINYINT, поле года - на тип YEAR, типа MONTH не нашлось.
А по поводу primary key на userID, странно, посмотрел в базу, но primary key на нем нет. Наверное, когда писал ответ, брал запрос с первоначальной базы.
Payed - сумма оплаты за месяц без копеек.
Спасибо!
Неактивен