Добавьте еще одну таблицу для запроса и подсчета данных SQL - PullRequest
4 голосов
/ 25 января 2012

Я пытаюсь выбрать данные из 4-х таблиц (последняя таблица должна подсчитывать данные)

Моя структура таблиц MySQL

Пользователи

id
username

изображения

id
user_id
image

user_follow

id
user_id
follow_id

комментарии

id
user_id
image_id
text

Я получил этот SQL-запрос:

    $sql = "SELECT u.username as user, i.image as user_image, p.image, p.date
            FROM users u              
            LEFT JOIN user_follow f ON u.id = f.follow_id
            LEFT JOIN images p ON p.user_id = u.id
            LEFT JOIN images i ON i.id = (SELECT b.id FROM images AS b where p.user_id = b.user_id ORDER BY b.id DESC LIMIT 1)
            WHERE f.user_id = 3 OR p.user_id = 3       
            ORDER BY p.date DESC";

Эта строка возвращает текущее изображение пользователя (последнее изображение)

 LEFT JOIN images i ON i.id = (SELECT b.id FROM images AS b where p.user_id = b.user_id ORDER BY b.id DESC LIMIT 1)

возвращает все изображения от меня и моих друзей

[0] => Array
    (
        [user] => 8888
        [user_image] => second.jpg
        [image] => second.jpg
        [date] => 2012-01-24 14:42:27
    )

[1] => Array
    (
        [user] => 8888
        [user_image] => second.jpg
        [image] => first.jpg
        [date] => 2012-01-24 14:42:27
    )

[2] => Array
    (
        [user] => 3333
        [user_image] => ax46l7v7vugnesk10whk_339.jpg
        [image] => ax46l7v7vugnesk10whk_339.jpg
        [date] => 2012-01-24 01:54:19
    )

[3] => Array
    (
        [user] => 3333
        [user_image] => ax46l7v7vugnesk10whk_339.jpg
        [image] => aaaaaaaa.jpg
        [date] => 2012-01-24 01:49:57
    )

Я пытался добавить

 left join commentaries c ON c.user_id = u.id

и результат был

[2] => Array
    (
        [user] => 3333
        [user_image] => ax46l7v7vugnesk10whk_339.jpg
        [image] => ax46l7v7vugnesk10whk_339.jpg
        [date] => 2012-01-24 01:54:19
        [id] => 1
    )

[3] => Array
    (
        [user] => 3333
        [user_image] => ax46l7v7vugnesk10whk_339.jpg
        [image] => ax46l7v7vugnesk10whk_339.jpg
        [date] => 2012-01-24 01:54:19
        [id] => 2
    )

[4] => Array
    (
        [user] => 3333
        [user_image] => ax46l7v7vugnesk10whk_339.jpg
        [image] => aaaaaaaa.jpg
        [date] => 2012-01-24 01:49:57
        [id] => 1
    )

[5] => Array
    (
        [user] => 3333
        [user_image] => ax46l7v7vugnesk10whk_339.jpg
        [image] => aaaaaaaa.jpg
        [date] => 2012-01-24 01:49:57
        [id] => 2
    )

Дублировать пользователя, если у него есть комментарии (Кстати, [user] => 3333 имеют 2 комментария в примере)

Я пытаюсь добавить еще одну таблицу «комментарии» и подсчитать, сколько комментариев имеет каждое изображение (от меня и моих друзей), если нет комментариев с таким $ user_id, а затем вернуть 0

Ответы [ 2 ]

2 голосов
/ 25 января 2012

Вам необходимо использовать GROUP BY для подсчета строк в группах (в вашем случае комментарии для каждого изображения).Этот запрос должен помочь:

SELECT u.username as user, i.image as user_image, p.image, p.date,
            COALESCE ( imgcount.cnt, 0 ) as comments
            FROM users u              
            LEFT JOIN user_follow f ON u.id = f.follow_id
            LEFT JOIN images p ON p.user_id = u.id
            LEFT JOIN images i ON i.id = (SELECT b.id FROM images AS b where p.user_id = b.user_id ORDER BY b.id DESC LIMIT 1)
            LEFT JOIN 
            ( SELECT image_id, COUNT(*) as cnt FROM
                 commentaries 
              GROUP BY image_id  ) imgcount
            ON p.id = imgcount.image_id
            WHERE f.user_id = 3 OR p.user_id = 3       
            ORDER BY p.date DESC
2 голосов
/ 25 января 2012

Вы действительно знаете, как сделать вопрос запутанным. Проблема здесь в том, что вы не понимаете последствий своих объединений.

Используя ваш пример. У вас есть таблица (в данном случае пользователи), которая имеет отношение один ко многим к двум другим таблицам (изображения и комментарии).

Например:

         users
        /     \
  images       commentaries

Когда вы пытаетесь одновременно объединить обе эти связанные таблицы с вашей базовой таблицей, создается эквивалент полного внешнего соединения между двумя дочерними таблицами.

Это:

SELECT *
FROM users u
LEFT JOIN images p ON p.user_id = u.id
LEFT JOIN commentaries c ON c.user_id = u.id

точно такой же, как этот:

SELECT *
FROM images p
LEFT JOIN commentaries c ON c.user_id = p.user_id

(в пересчете на количество произведенных записей)

Было бы хорошо, если бы одна из дочерних таблиц имела отношение 1 к 1 с родительской таблицей, но это не так. Поскольку в обеих из них есть несколько записей, результатом является FULL OUTER JOIN, а результатом является умножение количества записей, созданных в выходных данных. Вывод будет содержать число или записей, равное количеству совпадающих записей в одной таблице, умноженному на количество совпадающих записей в другой таблице. Таким образом, поскольку в каждой таблице есть две записи, соответствующие этому user_id, результирующий набор содержит четыре записи.

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

Следующая строка очень запутанная.

посчитайте, сколько комментариев есть на каждой картинке

Если вы действительно хотите считать только записи из одной или другой таблицы, то группировка решит проблему умножения.

$sql = "SELECT u.username as user, i.image as user_image, p.image, p.date, c.commentcount
        FROM users u              
        LEFT JOIN user_follow f ON u.id = f.follow_id
        LEFT JOIN images p ON p.user_id = u.id
        LEFT JOIN images i ON i.id = (SELECT b.id FROM images AS b where p.user_id = b.user_id ORDER BY b.id DESC LIMIT 1)
        LEFT JOIN (SELECT x.user_id, COUNT(*) AS commentcount FROM commentaries x GROUP BY x.user_id) c ON c.user_id = u.id
        WHERE f.user_id = 3 OR p.user_id = 3       
        ORDER BY p.date DESC";

Проблема с этим, как было отмечено ранее, заключается в том, что она по сути не имеет ничего общего с изображениями. Нет прямой связи между изображениями и комментариями. Между таблицами существует только отношение «многие ко многим». Поэтому мне очень трудно быть уверенным, что это вам вообще поможет.

По сути, это только количество комментариев, которые есть у пользователя. Это не имеет ничего общего с изображениями. Вы можете использовать очень похожий код, чтобы сказать, сколько изображений имеет пользователь, но это не имеет никакого отношения к комментариям.

Если то, что вы хотите сделать, это определить, сколько из одного пользователя есть, если у пользователя вообще есть другой, то это ответит на этот вопрос. Вы просто добавили бы тест в предложение WHERE, чтобы определить, есть ли у пользователя необходимая связанная запись или нет.

Если вы сможете уточнить свои намерения, я смогу помочь больше. В противном случае, я надеюсь, что это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...