Представление MySQL не более одного типа

#mysql

#mysql

Вопрос:

Я создаю простой код отслеживания баннеров для веб-сайта. Это работает нормально, но два клиента доминируют в случайном запросе, потому что у них более одного баннера в этом местоположении. Иногда у них будет 2 из 3 или 3 из 3, показывающие, что это не то, чего хочет клиент. Вот мой текущий запрос для представления.

 SELECT * FROM banners 
WHERE location like '["2"]'
AND published = '1'
ORDER BY rand() 
LIMIT 3;
  

У меня есть другое поле под названием client. Я бы хотел выбирать только один из их баннеров в то время, когда их местоположение совпадает с «[«2″]». Заранее спасибо.

 | published | location | client  | img                 |
|-----------|----------|---------|---------------------|
| 1         | ["2"]    | ClientA | /banners/image1.jpg |
| 1         | ["2"]    | ClientA | /banners/image2.jpg |
| 1         | ["2"]    | ClientA | /banners/image3.jpg |
| 1         | ["2"]    | ClientB | /banners/image4.jpg |
| 1         | ["2"]    | ClientC | /banners/image5.jpg |
| 1         | ["2"]    | ClientD | /banners/image6.jpg |
  

Комментарии:

1. Не могли бы вы добавить некоторые примеры данных к вашему вопросу и вывод, который вы ищете?

2. К сожалению, вопрос отклоняется без предоставления конструктивных идей. В добавленном вами примере какой вывод вы хотите?

3. И еще раз мой комментарий, иллюстрирующий, насколько невежественны люди, был удален. Я хочу, чтобы представление загружало 3 баннера, но только по 1 на клиента. Спасибо за вашу готовность помочь.

4. Понял. В приведенном выше примере клиент A имеет 3 баннера. Вы хотите, чтобы случайный баннер из 3 отображался для клиента A, верно? Клиент B, C и D имеет по 1 баннеру каждый. Итак, ваш вывод будет содержать только 3 записи с отсутствующей записью для клиента A, B или C. Правильно?

5. @zedfox Это звучит довольно точно. всего 3 баннера, но никогда не более одного на клиента.

Ответ №1:

Используя ваш пример:

 create table banners (
    published int,
    location varchar(10),
    client varchar(10), 
    img varchar(100)
);

insert into banners values
(1, '["2"]', 'ClientA', '/banners/image1.jpg'),
(1, '["2"]', 'ClientA', '/banners/image2.jpg'),
(1, '["2"]', 'ClientA', '/banners/image3.jpg'),
(1, '["2"]', 'ClientB', '/banners/image4.jpg'),
(1, '["2"]', 'ClientC', '/banners/image5.jpg'),
(1, '["2"]', 'ClientD', '/banners/image6.jpg');
  

Один из способов сделать это — использовать что-то вроде этого:

 -- we'll use a temporary table to store some data
-- if that table exists, let's drop it first.
-- you can change the name from banners_007 to something else

drop table if exists banners_007;

-- create that table to store data temporarily
-- store all data from banners and add a random number to each row

create table if not exists banners_007 as 
select *, rand() as randomnumber from banners;

-- get client and the lowest random number
-- and get all records for that client (you'll get 1 record per client)
-- order those clients randomly
-- get the top 3 records

select a.* from banners_007 a
inner join (

  select client, min(randomnumber) as min_rn
  from banners_007
  group by client

) b on a.client = b.client and a.randomnumber = b.min_rn
order by rand()
limit 3;
  

Пример здесь: https://rextester.com/ZTGED79700