MySQL查询

时间:2016-07-05 23:17:38

标签: mysql sql-order-by group-concat

我遇到了一些查询问题。我想通过一些id来订购查询。这是我的疑问:

此查询不会按照我的意愿返回结果:(

SELECT *
FROM question q
INNER JOIN answer a ON a.question_id = q.question_id
WHERE q.lesson_id = 1
AND q.question_id IN (
    SELECT e.question_id
    FROM exame e
    WHERE e.inscription_id = 1
    AND e.lesson_id = 1
    AND e.attempt = 1
    ORDER BY e.question_id
) /*this subquery returns (10,2,1,8,3,12,4,11,14,7)*/
ORDER BY FIELD(q.question_id,(
    SELECT GROUP_CONCAT(DISTINCT ee.question_id ORDER BY ee.order_of_appearance SEPARATOR ',') AS final_order
    FROM exame ee
    WHERE ee.inscription_id = 1
    AND ee.lesson_id = 1
    AND ee.attempt = 1)
) /*this subquery returns (10,2,1,8,3,12,4,11,14,7)*/

如您所见,这两个子查询返回相同的结果(10,2,1,8,3,12,4,11,14,7)。如您所知,它们之间的区别在于第一个返回结果集,第二个只返回一个具有所有id连接的字段。

问题#1:如果我复制第一个子查询并将其写在第二个子查询所在的位置,我会收到此错误:

  

1242 - 子查询返回超过1行

所以我创建了第二个子查询(使用GROUP_CONCAT函数),但结果并不是我所期望的。结果按“question_id”排序,我希望它按“order_of_appearance”字段排序。

问题#2:如果我在ORDER BY子句中编写子查询,我不会得到“order_of_appearance”字段排序的结果,但是如果我删除了子查询并且我手动编写了id的数组,结果按“order_of_appearance”排序!! WHY ???

此查询返回我想要的结果!! :)

SELECT *
FROM question q
INNER JOIN answer a ON a.question_id = q.question_id
WHERE q.lesson_id = 1
AND q.question_id IN (
    SELECT e.question_id
    FROM exame e
    WHERE e.inscription_id = 1
    AND e.lesson_id = 1
    AND e.attempt = 1
    ORDER BY e.question_id
)
ORDER BY FIELD(q.question_id,10,2,1,8,3,12,4,11,14,7)

最后一个问题:是否有可能实现我想要的而无需手动编写id的数组?我需要以恐怖的方式做到这一点。

提前致谢! (我希望你能理解我的英语!)

1 个答案:

答案 0 :(得分:1)

我认为您需要使用FIND_IN_SET()代替FIELD()

参考手册:

  

FIELD(str,str1,str2,str3,...)

     

返回strstr1str2,...列表中str3的索引(位置)。如果未找到str,则返回0.

     

如果FIELD()的所有参数都是字符串,则所有参数都将作为字符串进行比较。如果所有参数都是数字,则将它们作为数字进行比较。否则,参数将被比较为double。

     

如果strNULL,则返回值为0,因为NULL无法与任何值进行相等性比较。 FIELD()ELT()的补充。

mysql> SELECT FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo');
    -> 2

mysql> SELECT FIELD('fo', 'Hej', 'ej', 'Heja', 'hej', 'foo');
    -> 0
  

FIND_IN_SET(str,strlist)

     

如果字符串str位于由N个子字符串组成的字符串列表strlist中,则返回1到N范围内的值。字符串列表是由以“,”字符分隔的子字符串组成的字符串。如果第一个参数是常量字符串而第二个参数是SET类型的列,则FIND_IN_SET()函数将被优化为使用位算术。如果str不在strliststrlist为空字符串,则返回0。如果任一参数为NULL,则返回NULL如果第一个参数包含逗号(“,”)字符,则此函数无法正常工作。

mysql> SELECT FIND_IN_SET('b','a,b,c,d');
    -> 2