如何在动态查询中模拟 WHERE 1?

How can I emulate WHERE 1 in a dynamic query?

我正在像这样动态地进行查询:

$query = "SELECT u.*
          FROM users u
          WHERE date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 1 $range))";

还有$range包含这样一个词:

switch ($_GET['range']){
   case "week":
      $range = "WEEK";
   case "month":
      $range = "MONTH";
   case "year":
      $range = "YEAR";
   case "ALL":
      $range = <I don't know what should I put here to get the expected result>;
}

正如我上面所说的,我想将某些东西设置为 $range 值,以使 WHERE 子句类似于 WHERE 1。我该怎么做?

或许在你的 where 子句中使用 case 语句?

 $query = "SELECT u.*
           FROM users u
           WHERE CASE {$range}
                 WHEN 'ALL' then TRUE
                 ELSE date_time > unix_timestamp(DATE_SUB(now()
                                  , INTERVAL 1 {$range}))
                 END";
switch ($_GET['range']){
  case "week":
  $range = "WEEK";
 case "month":
  $range = "MONTH";
 case "year":
  $range = "YEAR";
 case "ALL":
  $range = null;
}

$query = "SELECT u.*
      FROM users u
      WHERE 1=1 ";
if(!empty($range)) {
  $query .= " AND date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 1 $range))";
}

有条件地添加datetime where子句; WHERE 1=1 永远为真。所以下一个条件的结果将影响最终结果

我认为 Adam 的建议是这样的:

$where = '';

switch ($_GET['range']) {

    case "week":
       $where = "date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 1 WEEK))":
        break;

    case "month":
       $where = "date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 1 MONTH))":
        break;

    case "year":
       $where = "date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 1 YEAR))":
        break;

    default:
        $where = '';
}

$query = "SELECT u.* FROM users u WHERE $where";

假设使用其他标准进行报告?字符串连接变得混乱的地方。在部分之间添加 'AND'。完全抑制 WHERE 关键字?表示 SQL 查询的 OOP 代码可能有用。

让我们从您的 switch 语句没有 break 语句并且不会按您期望的方式工作这一事实开始。

这是我的建议:

$query = "SELECT u.*
          FROM users u";

$range = false;

if (isset($_GET['range'])) {    
    switch ($_GET['range']){
       case "week":
          $range = "WEEK";
          break;
       case "month":
          $range = "MONTH";
          break;
       case "year":
          $range = "YEAR";
          break;
       default:
          $range = false;
    }
} 


if ($range) {
  $query .= " WHERE date_time > unix_timestamp(DATE_SUB(now(), INTERVAL 1 $range))";
}

我会定义一个具有有效范围的数组并首先验证用户输入。然后动态构建查询。

$validRanges = [
    'year'  => 'YEAR',
    'month' => 'MONTH',
    'week'  => 'WEEK',
    'ALL'   => null
];

if (isset($_GET['range']) && !isset($validRanges[$_GET['range']])) {
    $range = $validRanges[$_GET['range']]);
} else {
    // it's up to you, what to do in this case
    throw new Exception('Range is not valid or missing');
}

if ($range === null) {
    $rangeCondition = '1=1';
} else {
    $rangeCondition = "date_time > unix_timestamp(NOW() - INTERVAL 1 $range)";
}

$query = "SELECT u.*
          FROM users u
          WHERE $rangeCondition";