• Как оптимизировать запрос получения рекомендуемых постов с одним из тех же тегов?

    jemunjho
    @jemunjho
    Несколько вопросов:
    1) Теги могут дублироваться? Или они уникальные?

    2) Один и тот же тег - может быть привязан к разным постам. Так ведь?
    Можно попробовать сделать следующее: разбить все на три таблицы:
    - posts: id / site_id / published_at
    - tags: id / name [и можно поставить еще ключ уникальности на поле name]
    - post_tag_binding: post_id / tag_id [и поставить уникальный составной ключ на post_id + tag_id]

    3) Тогда запрос, приблизительно, будет выглядеть вот как-то так:
    select
    	p.id
    from posts as p, post_tag_binding as p_t_b
    where p.site_id = 124 and 
          p.id != 123 and 
          p.id = p_t_b.post_id and 
          p_t_b.tag_id in (
          	select 
          		p_t_b2.tag_id
          	from post_tag_binding as p_t_b2
          	where p_t_b2.post_id = 123
          )

    4) Один и тот же пост - может быть привязан к разным сайтам? Если да, то нужно сделать еще одну таблицу: post_site_binding, в которой будут содержаться поля - post_id / site_id. Это немного усложнит выборку, но не значительно. И так же - можно будет сделать уникальный ключ по двум этим полям.

    Я бы предложил следующую структуру:
    - posts: id / title / description / created_at и т.д.
    - tags: id / name [и можно поставить еще ключ уникальности на поле name]
    - sites: id / name [и можно поставить еще ключ уникальности на поле name]
    - post_tag_binding: post_id / tag_id [и поставить уникальный составной ключ на post_id + tag_id; дополнительно - сюда можно будет добавить еще site_id, если предполагается, что на разных сайтах может быть разный набор тегов для одного и того же поста]
    - post_feed: post_id / site_id / published_at [т.е. делаем еще одну таблицу, в которой будем хранить - даты, когда и на какой сайт данный пост был опубликован]
    Ответ написан
  • Как правильно сделать выборку один-ко-многим?

    jemunjho
    @jemunjho
    Несколько возможных вариантов:
    1) Подобный вопрос. Используйте group by post_id + group_concat для tag.name
    2) JSON_ARRAYAGG(col_or_expr). Т.е. формировать сразу JSON массив
    Ответ написан
    1 комментарий
  • Не раскрытая тайна LEFT JOIN?

    jemunjho
    @jemunjho
    Используйте GROUP BY + GROUP_CONCAT
    Либо сделайте пост-обработку результатов SQL запроса, сгруппировав данные по ID пользователя

    SELECT GROUP_CONCAT(post_comment.comment_content SEPARATOR ' ') FROM users GROUP BY users.user_id;
    Ответ написан
    1 комментарий
  • Как создать учет и отображение свободных мест?

    jemunjho
    @jemunjho
    Воздушное судно
    - id судна (pk, a_i)
    - бортовой номер (unique)
    - количество мест
    - тип судна (id из следующей таблицы)

    Типы воздушных суден
    - id типа
    - название (самолет, вертолет, да что угодно)

    Рейс
    - id рейса (pk, a_i)
    - название рейса
    - дата рейса
    - количество свободных мест (опционально)
    - количество занятых мест (опционально)

    Связующая таблица самолет-рейс
    - id самолета (id, 1-я таблица)
    - id рейса (id, 2-я таблица)

    Пассажиры
    - id пассажира (pk, a_i)
    - фамилия
    - имя

    Регистрация на рейс
    - id рейса
    - id пассажира
    - дата регистрации

    Занятые места
    - id рейса
    - id пассажира
    - номер места из таблицы ниже

    Места в воздушном судне
    - id места
    - id судна
    - номер места

    Я бы такую структуру сделал.
    Количества мест - опциональны, их можно рассчитывать по таблице с регистрацией на рейс.

    Исходя из двух таблиц - данную задачу решить сложно: т.к. это получается ни разу не система для управления аэропортом + в таблице с рейсами - будет постоянное дублирование данных в том случае, если их не выносить в отдельную сущность.
    Ответ написан
    1 комментарий
  • Как осуществить поиск не повторяющихся записей?

    jemunjho
    @jemunjho
    А зачем здесь подзапрос, если таблица одна и та же?

    SELECT DISTINCT
        email,
        phone
      FROM 
        table


    Но если это временная таблица - то можно просто напросто сделать выборку с подзапросом как-то так:
    SELECT * FROM table1 t1, (
    SELECT DISTINCT
        email,
        phone
      FROM 
        table) AS t2
    WHERE t1.email = t2.email AND t1.phone = t2.phone
    Ответ написан
    8 комментариев
  • Как в MySQL сделать сложную выборку из двух и более таблиц?

    jemunjho
    @jemunjho
    А зачем тут джойн? Просто выбираете все send_id с user_id = 2 и исключаете их из основной таблицы.

    select
    	*
    from project_calculation_send as p
    where p.send_id not in (select send_id from project_calculation where user_id = 2)
    Ответ написан
  • Как удалить старые записи одного типа, оставив самые свежие?

    jemunjho
    @jemunjho
    Если я не ошибаюсь, то MySQL не позволяет удалять данные из той же самой таблицы, из которой делается выборка в подзапросе для выбора данных. Лучше все таки - эту задачу разбить на две:
    1) Выбрать всех уникальных user_id и их MAX(date), с группировкой по user_id;
    2) Удалить информацию по каждому пользователю через обычный DELETE ... WHERE user_id = ... AND date < выбранной.

    Если хотите сделать удаление именно на стороне MySQL - то можно сделать хранимую процедуру, куда передавать user_id и дальше все нужные операции проводить уже в ней.

    Но если нужно одним запросом, то можно попробовать обернуть в подзапрос.

    delete from test where id in (
    select t3.id from (
    select
           id
    from test AS t1, (
               select
      t.user_id,
      MAX(t.date) AS date
    from test as t
    group by t.user_id) AS t2 where t1.user_id = t2.user_id AND t1.date < t2.date
    ) AS t3
    );


    Но это такое себе решение.
    Ответ написан
  • Как составить запрос?

    jemunjho
    @jemunjho
    SELECT
    	*
    FROM `Quests` AS q1
    WHERE q1.`id` NOT IN (
    	SELECT 
    		`questId`
    	FROM `QuestActive` AS q2
    	WHERE q2.`userid` IN (перечисление IDшников)
    )
    Ответ написан