如何根据特定规则对PHP / MySQL查询进行排序以按时间排序?

时间:2012-01-20 06:20:26

标签: php mysql sql-order-by

在我的应用程序中,用户可以选择何时应该给出特定项目(上午,下午,晚上,午夜或根据需要)。我需要打印一个摘要页面,显示应该给出每个项目的时间。我尝试为排序顺序设置的规则如下:

  1. 项目应始终按时间顺序显示 早上好,最后一个午夜
  2. 有多次的项目 给定的,应该以最少的次数进行排序 (即如果项目#2将在下午,午夜和作为 需要和第3项应该在下午,晚上,午夜和 根据需要,首先应列出第2项)
  3. 仅根据需要提供的项目应列在最后
  4. 以下是一个例子:

    • 项目#1:早上,晚上
    • 项目#2:下午,午夜,需要
    • 项目#3:下午,晚上,午夜,需要
    • 项目#4:晚上
    • 项目#5:如需要

    我正在使用PHP和MySQL,这是我目前的查询:

    $sth = $dbh->query("SELECT morning
                               afternoon,
                               evening
                               midnight
                               as_needed
                        FROM times                  
                        WHERE user_id = $user_id
                        ORDER BY as_needed, 
                                 morning DESC, 
                                 afternoon DESC, 
                                 evening DESC, 
                                 midnight DESC", PDO::FETCH_ASSOC);
    

    关于如何实施上述规则的任何想法?

3 个答案:

答案 0 :(得分:1)

詹姆斯的回答几乎就是我如何编码,但在他的例子中,not_as_needed_times没有正确排序,因为你问过最少次数的项目应该先行。

编辑:好的,这个庞然大物会照顾everything

$sth = $dbh->query("SELECT
  (as_needed + morning + afternoon + evening + midnight) AS total_items,
  IF((morning + afternoon + evening + midnight) = 0, 0, 1) AS not_as_needed_times, 
  morning, afternoon, evening, midnight, as_needed
  FROM times
  WHERE user_id = $user_id
  ORDER BY not_as_needed_times DESC, morning DESC, total_items ASC, afternoon DESC, total_items ASC, evening DESC, total_items ASC, midnight DESC, total_items ASC
");

首先我们将not_as_needed_times移动到最后,然后我们将morning = 1的记录推送到顶部并按选定次数排序,然后我们移动tuesday = 1的记录,依此类推。

答案 1 :(得分:0)

如果早晨等是数字,你可以这样做:

SELECT (morning + afternoon + evening + midnight + as_needed) as total_items, 
      IF((morning + afternoon + evening + midnight) = 0, 0, 1) as not_as_needed_items, 
 morning, afternoon, evening, midnight, as_needed 
FROM times 
WHERE user_id = $user_id 
ORDER BY not_as_needed_items desc, total_items asc

降序的not_as_needed使得as_needed只能得到底部求解(3)。 total_items asc按#total items排序,求解(2)。由于所有时间都在一行中,所以只需要显示逻辑(1)。

编辑:在其他海报中加入针对not_as_needed_items的修复。

答案 2 :(得分:-1)

如果每行只使用一个时间帧,则表格不应包含每个时间范围的列。您应该只有一列来标识记录的时间范围。所以让你的桌子像这样。

times
---------------
row_id
user_id
timeframe_id
rule


timeframes
---------------
timeframe_id
name
order

查询

SELECT * FROM times t INNER JOIN timeframes tf USING (timeframe_id) WHERE user_id = $user_id ORDER BY tf.order

辅助查询

SELECT * FROM times t INNER JOIN timeframes tf USING (timeframe_id) WHERE user_id = $user_id AND tf.timeframe_id = '$selected_timeframe' ORDER BY tf.order

您可以使用时间范围表中的排序编号排列时间范围顺序。然后每行将与时间帧相关联。完成后,您可以更改时间范围的顺序而无需修改代码,也无需更改规则表中的每一行(也称为时间)。

相关问题