使用IN子句按顺序获取记录 - 在IN子句中具有重复值

时间:2017-11-09 05:59:33

标签: php mysql foreach where

我有表格问题

id   | question    | question_level
______________________________________
1    | abc         | 1
______________________________________
2    | prs         | 3
______________________________________
3    | oesl        | 2
______________________________________
4    | ocsl        | 3
______________________________________ 
5    | qoindos     | 1
______________________________________
6    | xyz         | 3
______________________________________
7    | mnlop       | 2
______________________________________
8    | cllse       | 2
______________________________________ 
9    | teuosn      | 4
______________________________________
10   | ulcd        | 2
______________________________________

我想选择10条与问题级别匹配的记录 我有级别的顺序,我希望所有记录如下

1,2,1,2,3,2,4,2,3,3

输出应为

id   | question    | question_level
______________________________________
1    | abc         | 1
______________________________________
3    | oesl        | 2
______________________________________
5    | qoindos     | 1
______________________________________
7    | mnlop       | 2
______________________________________ 
2    | prs         | 3
______________________________________
8    | cllse       | 2
______________________________________
9    | teuosn      | 4
______________________________________
10   | ulcd        | 2
______________________________________ 
4    | ocsl        | 3
______________________________________
6    | xyz         | 3
______________________________________

我尝试了不同的解决方案,但无法获得正确的输出 尝试使用field,find_in_set但没有成功。 提及[Force MySQL to return duplicates from WHERE IN clause without using JOIN/UNION? 但只能按计数递增计数和记录

我尝试了下面的解决方案

SELECT question_level FROM `tbl_questions` WHERE `question_level` IN (1,2,1,2,3,2,4,2,3,3) ORDER BY FIELD(`question_level`, 1, 2, 1, 2, 3, 2, 4, 2, 3, 3) LIMIT 10

SELECT question_level FROM tbl_questions WHERE FIND_IN_SET(`question_level`,'1,2,1,2,3,2,4,2,3,3');

SELECT question_level,question_object_name,question_object_path,question_answer
        FROM tbl_questions e JOIN (SELECT 1 AS question_level UNION ALL
              SELECT 2 UNION ALL
              SELECT 1 UNION ALL
              SELECT 2 UNION ALL
              SELECT 3 UNION ALL
              SELECT 2 UNION ALL
              SELECT 4 UNION ALL
              SELECT 2 UNION ALL
              SELECT 3 UNION ALL
              SELECT 3
             ) matches
             USING (question_level) LIMIT 10;

我尝试使用foreach循环但每次在问题级别与值匹配时获得相同的记录

$array = explode(',', '1,2,1,2,3,2,4,2,3,3')
foreach ($array as $value) {
 SELECT question_level FROM tbl_questions 
 WHERE question_level = $value;
}

如果在mysql中不可能,那么可以使用php实现。

提前致谢

2 个答案:

答案 0 :(得分:0)

从逻辑上讲,你不可能做你想做的事,我会尝试用你的订单选择来解释

 ORDER BY FIELD(`question_level`, 1, 2, 1, 2, 3, 2, 4, 2, 3, 3)

所以我们要1然后再21 question_level。现在在表格中我们有这些价值观。我只关心问题#level#1,这就是我需要表达我的观点。

id   | question    | question_level
______________________________________
1    | abc         | 1
______________________________________
5    | qoindos     | 1
______________________________________

正如您所看到的,我们有question_level=1的行现在,系统将如何确定哪个级别1是第一个,哪个级别是第二个。没有办法决定如何做到这一点。因此,无论数据库无法按您希望的方式对其进行排序。没有更多的信息来做出这个选择,即使对它进行排序也无法构建循环。您可以做的最好的事情是按主键排序,然后按级别排序。你最不可能在服务器端做这件事。

我认为您在这里犯的错误是,您需要使用问题实际的唯一ID,如果您对每个级别的问题有限制,则需要单独解决。

希望这是有道理的。

如果您尝试在x级别选择n个随机问题,这些问题可以很容易地解决。例如,如果你想要

  • lv 1的2x问题
  • lv 2的4x问题
  • lv 3的3x问题
  • lv 4的1x问题。

这可以通过对级别的四个简单查询来计算,同时在id字段上随机排序并使用该级别的适当限制子句。按照他们的方式,这些是您问题中的级别数。

如果您确实想要在给定级别选择随机问题,您可能希望使用子查询来执行此操作。 RAND()有一些性能损失,您可以通过随机化主键然后加入表格以便在订购后将其余数据拉出来。但是,你应该对它进行基准测试

这就是一个例子。

SELECT
    q1.*
FROM 
    tbl_questions AS q1
JOIN
(
    SELECT
        id
    FROM
        tbl_questions
    WHERE
        question_level = 1
    ORDER BY RAND() LIMIT 2
) AS q2 USING( id )

虽然我不得不承认我从来没有尝试过这个只是我的想法。

答案 1 :(得分:0)

我使用php

对此进行了排序
$sequence = "1,2,1,2,3,2,4,2,3,3";
$seq_arr = explode(',', $sequence);
  

第1步:

创建数组以存储所有细节

$questions = array(); // to store all questions 
$final_questions = array(); // tos store final questions in the sequence needed
$level_1 = array(); // level 1 questions
$level_2 = array(); // level 2 questions
$level_3 = array(); // level 3 questions
$level_4 = array(); // level 4 questions
$level_5 = array(); // level 5 questions
  

第2步:

从Db中选择所有数组并根据问题级别存储在每个数组中

$this->db->select(*);
$this->db->from(questions);
$query = $this->db->get();
$result = $query->result_array();
for ($i=0; $i<count($result) ; $i++) {
 if(isset($result[$i]) && !empty($result[$i])){
  if($result[$i]['question_level'] == 1)
  {
    $level_1[] = $result[$i];
  }
  if($result[$i]['question_level'] == 2)
  {
    $level_2[] = $result[$i];
  }
  if($result[$i]['question_level'] == 3)
  {
    $level_3[] = $result[$i];
  }
  if($result[$i]['question_level'] == 4)
  {
    $level_4[] = $result[$i];
  }
  if($result[$i]['question_level'] == 5)
  {
    $level_5[] = $result[$i];
  }
 }
}
  

第3步:

将序列与所有数组匹配并存储到最终数组中。

foreach ($seq_arr as $key => $value) {
  if($value == 1)
    {
         for ($i=0; $i < count($difficulty_array) ; $i++) 
          { 
             if(isset($level_1[$i]) && !empty($level_1[$i])){
               if(!in_array($level_1[$i], $final_questions))
                 {
                    $final_questions[] = $level_1[$i];
                    break;
                 } 
             }
          }
     }
   if($value == 2)
     {
         for ($i=0; $i < count($difficulty_array) ; $i++) 
          { 
             if(isset($level_2[$i]) && !empty($level_2[$i])){
               if(!in_array($level_2[$i], $final_questions))
                 {
                    $final_questions[] = $level_2[$i];
                    break;
                 } 
              }
           }
      }
    if($value == 3)
      {
        for ($i=0; $i < count($difficulty_array) ; $i++) 
         { 
            if(isset($level_3[$i]) && !empty($level_3[$i])){
               if(!in_array($level_3[$i], $final_questions))
                 {
                    $final_questions[] = $level_3[$i];
                    break;
                 } 
             }
          }
     }
     if($value == 4)
       {
          for ($i=0; $i < count($difficulty_array) ; $i++) 
            { 
              if(isset($level_4[$i]) && !empty($level_4[$i])){
                if(!in_array($level_4[$i], $final_questions))
                   {
                     $final_questions[] = $level_4[$i];
                     break;
                   } 
              }
            }
       }
     if($value == 5)
       {
          for ($i=0; $i < count($difficulty_array) ; $i++) 
             { 
                if(isset($level_5[$i]) && !empty($level_5[$i])){
                   if(!in_array($level_5[$i], $final_questions))
                      {
                         $final_questions[] = $level_5[$i];
                         break;
                       } 
                 }
             }
          }
      }
print_r($final_questions);