【问题标题】:PDO How to select where two values from different arrays in 2 different columsPDO 如何从 2 个不同列中的不同数组中选择两个值
【发布时间】:2012-11-30 20:56:35
【问题描述】:

我的数据库中有 2 列包含文本(Products CodeProducts Variant)。

例如:
Products Code 包含以下文本:C050101、C070104

Products Variant 包含以下文本:RED, NULL

我想选择所有行 WHERE Code = Products Code AND Variant = Products Variant
根据我上面写的例子,我应该得到 2 行:
第一行WHERE Code=C050101 and Variant=RED
第二行 WHERE Code=C070104 and Variant IS NULL IS NULL

我不知道该怎么做...
如果我只需要选择所有行WHERE Code = Products Code >>

,我会知道该怎么做
$arr = array('C050101','C070104');
$inclause = implode(',',array_fill(0,count($arr),'?'));
$stockstmt = $pdo->prepare(sprintf("SELECT `id`, `WebTitle`, `StockCode` FROM `stock` WHERE `StockCode` IN(%s)",$inclause));
$stockstmt->execute($arr);

非常感谢您的帮助。
谢谢!

【问题讨论】:

  • 你的意思是像WHERE code in (select ProductsCode from table)这样的东西吗?您的问题对什么起作用/不起作用感到困惑。
  • 我没有说有什么东西不工作。我只想选择使用比我上面发布的更复杂的查询.. 类似WHERE (Code="C050101" AND Variant="RED") OR (Code="C070104" AND Variant IS NULL)
  • 嗯,这就是你的答案,不是吗?通过添加要查询的两个字段来动态生成查询,或者创建一个临时表以在两个字段上连接。

标签: php sql arrays pdo printf


【解决方案1】:

您不能为此使用IN 谓词,因为IN 只知道如何与= 进行比较,并且您需要进行不同的比较以处理NULL。

MySQL 有一个非标准的null-safe equal operator <=>,它知道 NULL=NULL 为真,NULL = 'RED' 为假。

如果您使用 MySQL 以外的其他东西,您的 RDBMS 可能支持 IS [NOT] DISTINCT,这是类似谓词的标准 SQL 语法。

我测试了以下内容,它可以工作:

$arr = array('C050101','RED', 'C070104', NULL);

$sql = "SELECT `id`, `WebTitle`, `StockCode` FROM `stock`
  WHERE (`StockCode`, `StockVariant`) <=> (?, ?)
     OR (`StockCode`, `StockVariant`) <=> (?, ?)";

$stockstmt = $pdo->prepare($sql);
if ($stockstmt === false) { die(print_r($pdo->errorInfo(), true)); }

$status = $stockstmt->execute($arr);
if ($status === false) { die(print_r($stockstmt->errorInfo(), true)); }

我会告诉你如何构建谓词列表。


你的评论:

不建议使用文字字符串“NULL”来表示缺失或不适用的值。这就是 NULL 在 SQL 中的用途。

如果您想要一个使构建谓词更加动态的函数,请尝试以下操作:

function lookformultiplethings(array $arr)
{
  global $pdo;

  $where = array();
  $values = array();
  foreach ((array) $arr as $term) {
    $where[] = '('
        . join(',', array_map(function ($col) {return "`$col`";}, array_keys($term)))
        . ') <=> ('
        . join(',', array_fill(0,count($term),'?'))
        . ')';
    $values = array_merge($values, array_values($term));
  }
  $sql = "SELECT `id`, `WebTitle`, `StockCode` FROM `stock` ";
  if ($where) {
    $sql .= "WHERE " . join(' OR ', $where);
  }

  $stockstmt = $pdo->prepare($sql);
  if ($stockstmt === false) { die(print_r($pdo->errorInfo(), true)); }

  $status = $stockstmt->execute($values);
  if ($status === false) { die(print_r($stockstmt->errorInfo(), true)); }

  print_r($stockstmt->fetchAll());
}

lookformultiplethings(array(
  array('StockCode' => 'C050101', 'StockVariant' => 'RED'),
  array('StockCode' => 'C070104', 'StockVariant' => 'NULL'),
));

请注意,您传递的数组的键是合法的列名。也就是说,除非您根据真实列的白名单进行验证,否则不要让用户输入设置列名。

【讨论】:

  • my NULL is NULL as text > $arr = array('C050101','RED', 'C070104', 'NULL'); 尽管你在这里给出了很好的解决方案,将两个数组组合成一个数组,其中每个奇数键包含代码,每个偶数键包含变体并使用查询以您的格式。然而,你的解决方案不是动态的,你的基础是只有 2 个代码和 2 个变体,我需要更动态的东西
猜你喜欢
  • 2017-01-26
  • 2020-09-28
  • 2017-11-11
  • 1970-01-01
  • 2016-05-14
  • 2012-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多