2013-07-15 65 views
0

我有一个列表和一个列表项目表。我想制定一个查询来为列表中的每个项目选择一个列表项目。下面是一些简单的数据来说明我的问题:如何为每个父记录选择一个子表项?

'lists' table 
id updated share 
--- ---------- ----- 
1 2013-07-11 1 
2 2013-07-13 0 
3 2013-07-15 1 
4 2013-07-14 0 
5 2013-07-14 1 

'list_items' table 
id l_id description sort likes 
-- ---- ----------- ---- ----- 
1 1 hello  0  3 
2 1 goodbye  0  0 
3 1 thanks  0  4 
4 2 ok   0  0 
5 3 love  0  2 
6 3 hate  1  1 
7 4 celebrate 0  0 
8 5 party  0  1 
9 5 summer  1  5 
10 5 winter  2  2 

现在说我想从每个共享列表(份额= 1),得到的第一个项目。首先,我的意思是如果列表项按“排序”排序。

基于上述数据预期的结果将是:

lists.id id l_id description sort likes 
-------- -- ---- ----------- ---- ----- 
    1  1 1 hello  0  3 
    3  5 3 love  0  2 
    5  8 5 party  0  1 

更新: 我努力让我的头周围的peterm和hims056和而提供的解决方案凯拉的解决方案看起来更象是我可以按照它没有返回正确的结果。以思想从这些解决方案我有裂纹,在它自己与

SELECT * FROM (
    SELECT lists.id AS listid, lists.share, list_items.* 
    FROM list_items, lists 
    WHERE lists.id = l_id 
    AND lists.share = 1 
    ORDER BY sort) q 
    GROUP BY q.listid 

这似乎是工作上来,但作为peterm指出,在SELECT子句中的列不属于组的一部分by子句中的值可能不明确。

我虽然有人会想出使用LIMIT的解决方案,因为这是我首先想到的方式。您可以返回其允许通过简单的共享目录ID:

SELECT lists.id FROM lists WHERE share = 1 

和给定列表ID可以通过返回顶部列表项:

SELECT lists.id AS listid, lists.share, list_items.* 
FROM list_items, lists 
WHERE lists.id = l_id 
AND lists.id = 1 
ORDER BY sort 
LIMIT 1 

但是有没有把这些2的方式声明一起返回每个允许共享的列表的顶部列表项目?

+0

没有任何答案对您有帮助吗? – hims056

回答

1

修订为了确保sort获得第一每组有为了尽量

SELECT q.l_id list_id, q.id, i.description, i.sort, i.likes 
    FROM 
(
    SELECT l_id, id, @n := IF(@g = l_id, @n + 1, 1) n, @g := l_id g 
    FROM 
    (
    SELECT i.l_id, i.id 
     FROM list_items i JOIN lists l 
     ON i.l_id = l.id 
    WHERE l.share = 1 
    ORDER BY l_id, sort, id 
) b CROSS JOIN (SELECT @n := 0, @g := 0) a 
    HAVING n = 1 
) q JOIN list_items i 
    ON q.id = i.id 

输出示例:

 
| LIST_ID | ID | DESCRIPTION | SORT | LIKES | 
--------------------------------------------- 
|  1 | 1 |  hello | 0 |  3 | 
|  3 | 5 |  love | 0 |  2 | 
|  5 | 8 |  party | 0 |  1 | 

这里是SQLFiddle演示

+0

OP说:*首先,我的意思是,如果列表项按'sort'排序*因此,当[sort is 1 where hello]时,此查询将不起作用(http://sqlfiddle.com/#!2/ 4519f6/1) – hims056

+0

[Still description = hello](http://sqlfiddle.com/#!2/4519f6/10)即将到来,我们把排序= 1。 – hims056

+1

@ hims056公平的。谢谢。它是固定的。 – peterm

1
SELECT lists.id, list_items.id, l_id, description, sort, likes 
    FROM (SELECT * FROM lists WHERE share = 1) lists 
    LEFT JOIN (SELECT * FROM list_items GROUP BY l_id) list_items 
    ON lists.id = l_id 
+0

看起来它没有根据排序顺序选择正确的列表项,但我喜欢更简单的方法。我想出了SELECT * FROM( SELECT lists.id AS listid,lists.share,list_items。* FROM list_items,lists WHERE lists.id = l_id AND lists.share = 1 ORDER BY sort) q GROUP BY q.listid'但我不是100%确定它是否正确 – AidanCurran

+0

我认为它很好,只要你能显示你想要的所有数据,但请注意你的连接,试着添加另一个可能的输入数据,并确保它会显示稳定的结果 – kayla

0

既然你想获得最低list_items.id排序条件为list_items.sort,你需要这样的执行双重嵌套查询:

SELECT tbl.l_id list_id, tbl.minID, li.description, li.sort, li.likes 
FROM list_items li 
JOIN 
(
    SELECT l.l_id,MIN(l.id) minID FROM list_items l 
    JOIN 
    (
     SELECT li.l_id,MIN(li.sort) sort FROM list_items li 
      JOIN lists l ON li.l_id = l.id WHERE l.share = 1 
     GROUP BY li.l_id 
    ) l2 
    ON l.l_id = l2.l_id 
    AND l.sort = l2.sort 
    GROUP BY l.l_id 
) tbl 
ON li.id = tbl.minID; 
相关问题