Mysql-запрос в базе данных drupal - групповой максимум с дублирующимися данными - PullRequest
2 голосов
/ 19 мая 2010

Я работаю над запросом mysql в базе данных Drupal, который объединяет пользователей и два разных типа контента cck. Я знаю, что люди постоянно обращаются за помощью по групповым максимальным запросам ... Я сделал все возможное, но мне нужна помощь.

Это то, что я имею до сих пор:

# the artists
SELECT
    users.uid,
    users.name AS username,
    n1.title AS artist_name
FROM users
LEFT JOIN users_roles ur 
    ON users.uid=ur.uid
INNER JOIN role r 
    ON ur.rid=r.rid 
    AND r.name='artist'
LEFT JOIN node n1 
    ON n1.uid = users.uid 
    AND n1.type = 'submission'
WHERE users.status = 1
ORDER BY users.name;

Это дает мне данные, которые выглядят как:

uid username artist_name
1   foo      Joe the Plumber
2   bar      Jane Doe
3   baz      The Tooth Fairy

Также у меня есть этот запрос:

# artwork
SELECT
    n.nid, 
    n.uid,
    a.field_order_value
FROM node n
LEFT JOIN content_type_artwork a 
    ON n.nid = a.nid
WHERE n.type = 'artwork' 
ORDER BY n.uid, a.field_order_value;

Что дает мне такие данные:

nid uid field_order_value
1   1   1
2   1   3
3   1   2
4   2   NULL
5   3   1
6   3   1

Дополнительная информация по теме:

  • nid является первичным ключом для произведения искусства
  • у каждого художника есть одна или несколько работ
  • действительными данными для field_order_value является NULL, 1, 2, 3 или 4
  • field_order_value не обязательно уникален для каждого художника - у художника может быть 4 работы с field_order_value = 1.

Мне нужна строка с минимальным значением field_order_value из моего второго запроса, объединенная с информацией об исполнителе из первого запроса. В случаях, когда field_order_value не является ценной информацией (либо потому, что Художник использовал дублированные значения среди своих произведений искусства, либо оставил это поле NULL), я хотел бы строку с минимальным значением nid из второго запроса.


Решение

Используя метод «разделяй и властвуй» в качестве стратегии и представления MySQL в качестве техники, и обращаясь к этой статье о максимальных групповых запросах , я решил свою проблему.

Создать представление

# artists and artworks all in one table
CREATE VIEW artists_artwork AS
SELECT
    users.uid,
    users.name AS artist,
    COALESCE(n1.title, 'Not Yet Entered') AS artist_name,
    n2.nid, 
    a.field_image_fid, 
    COALESCE(a.field_order_value, 1) AS field_order_value
FROM users
LEFT JOIN users_roles ur 
    ON users.uid=ur.uid
INNER JOIN role r 
    ON ur.rid=r.rid 
    AND r.name='artist'
LEFT JOIN node n1 
    ON n1.uid = users.uid 
    AND n1.type = 'submission'
LEFT JOIN node n2
    ON n2.uid = users.uid
    AND n2.type = 'artwork'
LEFT JOIN content_type_artwork a ON n2.nid = a.nid
WHERE users.status = 1;

Запрос представления

SELECT
    a2.uid, 
    a2.artist, 
    a2.artist_name, 
    a2.nid, 
    a2.field_image_fid, 
    a2.field_order_value
FROM (
    SELECT
        uid, 
        MIN(field_order_value) AS field_order_value
    FROM artists_artwork
    GROUP BY uid
    ) a1
JOIN artists_artwork a2
    ON a2.nid = (
        SELECT
            nid
        FROM artists_artwork a
        WHERE a.uid = a1.uid
            AND a.field_order_value = a1.field_order_value
        ORDER BY
            uid ASC, field_order_value ASC, nid ASC
        LIMIT 1
)
ORDER BY artist;

1 Ответ

2 голосов
/ 19 мая 2010

Простым решением этой проблемы может быть создание представлений в вашей базе данных, которые затем можно объединить. Это особенно полезно, если вы часто хотите увидеть промежуточные данные таким же образом в каком-то другом месте. Хотя можно объединить один огромный запрос, иногда я просто использую подход «разделяй и властвуй».

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