drupal数据库中的mysql查询 - 具有重复数据的groupwise最大值

时间:2010-05-19 17:02:58

标签: mysql drupal

我正在Drupal数据库中处理一个mysql查询,它将用户和两种不同的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视图作为一种技术,并引用this article about groupwise maximum queries,我解决了我的问题。

创建视图

# 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 个答案:

答案 0 :(得分:2)

一个简单的解决方案是在数据库中创建可以连接在一起的视图。如果您经常希望在其他地方以相同的方式查看中间数据,这将特别有用。虽然可以将一个巨大的查询混合在一起,但我有时会采取分而治之的方法。