Отображение Рекомендуемого Элемента Из Базы Данных
У меня есть таблица базы данных, как показано ниже.
id, bungalow_name, type, address, featured
Бунгало можно разместить на домашней странице. Если показано бунгало, столбец featured
имеет значение 1
. У меня есть 50 бунгало в таблицах, и в данный момент времени представлено 5-7 бунгало.
Давайте предположим, что рекомендуемые названия бунгало такие, как показано ниже.
bungalow 1, bungalow 2, bungalow 3, .........., bungalow 6
Что я пытаюсь сделать, так это показывать на главной странице рекомендуемое бунгало на каждый день. И я хочу сделать цикл, как показано ниже, как показано ниже, для каждого месяца. Учитывая, что я не хочу показывать бунгало случайным образом при каждой загрузке страницы. Я хочу показывать в день по одному бунгало.
today -> bungalow 1
tomorrow -> bungalow 2
day after tomorrow -> bungalow 3
...
After bungalow 6, bungalow 1 is shown on the next day.
Как я могу это сделать? Возможно ли это вообще с SQL/PHP?
8 answers
Вы можете использовать этот запрос MySQL:
SELECT *
FROM Bungalows
WHERE id = (
SELECT b1.id
FROM
Bungalows b1 LEFT JOIN Bungalows b2
ON b1.id>b2.id AND b2.featured=1
WHERE
b1.featured=1
GROUP BY
b1.id
HAVING
COUNT(b2.id) = (SELECT
DATEDIFF(CURDATE(), '2013-05-06') MOD
(SELECT COUNT(*) FROM Bungalows WHERE Featured=1))
)
Пожалуйста, смотрите fiddle здесь . "2013-05-06" - это день, когда вы хотите начать показывать первое показанное бунгало. Они будут показаны упорядоченными по идентификатору, начиная с "2013-05-06".
РЕДАКТИРОВАТЬ
Следующий запрос вернет количество дней, прошедших с 2013-05-06:
SELECT DATEDIFF(CURDATE(), '2013-05-06')
Функция MOD вернет целое число, оставшееся от деления числа прошедших дней на число рекомендуемые строки:
SELECT DATEDIFF(CURDATE(), '2013-05-06') MOD
(SELECT COUNT(*) FROM Bungalows WHERE Featured=1)
Если есть 6 рекомендуемых бунгало, он вернет 0 в первый день, 1 во второй, 2, 3, 4, 5, а затем 0,1,2... снова.
В MySQL нет функции для возврата РАНГА (номера строки), поэтому вам придется как-то его имитировать. Я смоделировал это следующим образом:
SELECT b1.id, COUNT(b2.id)
FROM
Bungalows b1 LEFT JOIN Bungalows b2
ON b1.id>b2.id AND b2.featured=1
WHERE
b1.featured=1
GROUP BY
b1.id
Я присоединяюсь к столу Бунгало вместе с самим собой. Ранг идентификатора бунгало - это количество бунгало, у которых идентификатор меньше этого (следовательно, объединение b1.id >b2.id).
Затем я выбираю только строку которые имеют РАНГ, возвращаемый функцией выше:
ИМЕЯ ГРАФ(b2.id ) = (ВЫБРАТЬ DATEDIFF(CURDATE(), '2013-05-06') МОД (ВЫБЕРИТЕ КОЛИЧЕСТВО (*) ИЗ бунгало, ГДЕ Указано =1))
Если вы используете MySQL, мой первоначальный запрос может быть упрощен следующим образом:
SELECT b1.*
FROM
Bungalows b1 LEFT JOIN Bungalows b2
ON b1.id>b2.id AND b2.featured=1
WHERE
b1.featured=1
GROUP BY
b1.id
HAVING
COUNT(b2.id) = (SELECT
DATEDIFF(CURDATE(), '2013-05-06') MOD
(SELECT COUNT(*) FROM Bungalows WHERE Featured=1))
$dbh = new PDO(....); // use your connection data
$statement = $dbh->query("SELECT count(*) as size FROM bungalows where features = 1");
$data = $statement->fetchALL(PDO::FETCH_CLASS,"stdClass");
$i = date('z') % $data[0]->size;
$statement = $dbh->query("SELECT * FROM bungalows where features = 1 order by id LIMIT $i,1");
$bungalow = reset($statement->fetchALL(PDO::FETCH_CLASS,"stdClass"));
РЕДАКТИРОВАТЬ
- Удалены вызовы mysql_
- добавлено предложение о заказе, как предложила фтиелла (спасибо:))
Попробуйте этот запрос, он будет работать в каждом случае с увеличением количества показываемых бунгало и т. Д., И ежедневно будет выдавать другой.
Здесь в запросе я присваиваю номера каждому показанному бунгало от 0 до n, а затем получаю, разделив общее количество показанных бунгало на дату, когда я нахожу отображаемое бунгало.
Запрос 1:
select
a.*
from
(select
@rn:=@rn+1 as rId,
b.cnt,
a.*
from
Bunglows a
join
(select @rn:=-1) tmp
join
(select
count(*) as cnt
from
Bunglows
where
featured=1)b
where
featured=1) a
where
datediff(CURDATE(), '2013-01-01')%a.cnt=a.rId
| RID | CNT | ID | BUNGALOW_NAME | FEATURED |
---------------------------------------------
| 3 | 4 | 6 | bungalow 4 | 1 |
РЕДАКТИРОВАТЬ
select count(*) as cnt from Bunglows where featured=1
Этот запрос находит общее количество показанных бунгало
select @rn:=@rn+1 as rId, b.cnt, a.* from Bunglows a join (select @rn:=-1) tmp join select count(*) as cnt from Bunglows where featured=1
Этот запрос добавляет номер строки a к каждому показанному бунгало, начиная с 0 до n
Основной запрос сначала находит дату, отличную от текущей даты и старой даты, и находит значение мод по общему количеству показанных бунгало, которое будет давать значения от 0 до n-1, и я добавил предложение where, которое проверяет, чтобы разделенное значение было равно идентификатору строки, который мы назначили..
Надеюсь, это поможет...
Основная концепция моего ответа заключается в том, чтобы;
1/ Создайте список всех рекомендуемых бунгало. Это достигается в подзапросе, где каждому бунгало присваивается уникальный порядковый номер. Код для поля seq_num основан на ответе здесь
2/ Выберите одно бунгало из списка в зависимости от того, где мы находимся в этом месяце. Для этого я смотрю на день месяца на сегодня, используя код day(curdate())
, и нахожу мод этого числа к общему числу показанных бунгало.
select sq.bungalow_name
from (
select bungalow_name
,@curRow := @curRow + 1 AS seq_num
from table1, (SELECT @curRow := 0) r
where featured = 1
order by
bungalow_name desc
) sq
where sq.seq_num = mod(day(curdate()),(select count(*) from table1 where featured = 1))
Пример в этой скрипке SQL
Вы должны отслеживать последнюю дату отображения для каждой показанной записи (last_viewed
).
Для новых записей установите эту дату на день в прошлом, например, 2000-01-01.
Если есть запись с текущей датой, используйте ее.
В поле нет используйте запись с самой ранней датой.
SELECT *, IF(DATE(last_viewed)=CURDATE(), 1, 0) AS current
FROM #__bungalows
WHERE featured=1
ORDER BY current DESC, last_viewed ASC
LIMIT 0,1
Как и счетчик hit
в com_content
, вы должны добавить метод попадания в свою модель бунгало, который устанавливает столбец last_viewed
выбранного бунгало в now()
.
select ....
where featured = 1
limit DAYOFYEAR(NOW()) % (select count(*) from ... where featured = 1), 1
Я не уверен, разрешен ли подвыбор в пределе. Возможно, вам придется выполнить этот запрос отдельно. Это будет меняться каждый день. Проще простого выжать лимон.
Редактировать: для выполнения в 2 запросах
$query = "SELECT COUNT(*) FROM ... WHERE FEATURED = 1";
$count = intval(array_pop(mysql_fetch_assoc(mysql_query($query))));
$query = "
select ....
where featured = 1
limit DAYOFYEAR(NOW()) % {$count}, 1
";
ГОТОВО!
Оператор по модулю % делает свое дело:
Сначала добавьте столбец "счетчик int".
Затем пронумеруйте рекомендуемые столбцы, например, 1,2,3... если вы ленивы, вы можете использовать это:
set @cc=0;
update bungalows set counter=(select @cc:=@cc+1) where featured=1;
Теперь все готово, и вы просто можете сделать первый выбор:
select * from bungalows where featured=1 and counter%(select count(*) from bungalows where featured=1)=0;
И каждый раз, прежде чем вам понадобятся следующие рекомендуемые бунгало, делайте следующее:
update bungalows set counter=counter+1 where featured=1;
Затем снова:
select * from bungalows where featured=1 and counter%(select count(*) from bungalows where featured=1)=0;
...
update bungalows set counter=counter+1 where featured=1;
И так далее...
Проверьте здесь с помощью SQLFiddle
SELECT *
FROM bungalows b
JOIN (SELECT
( DAYOFMONTH(CURDATE() ) % COUNT(b2.id) ) AS slab,
COUNT(b2.id) AS total_count
FROM bungalows b2
WHERE b2.featured = 1) AS b3
WHERE IF(b3.slab = 0, b3.total_count, b3.slab) = (SELECT
COUNT(id)
FROM bungalows b1
WHERE b.id >= b1.id
AND b1.featured = 1)
AND b.featured = 1