复杂的SQL语句:如何选择与数组提供的两列条件相匹配的行



我有两个表

CREATE TABLE IF NOT EXISTS products ( 
product_id int(11) NOT NULL AUTO_INCREMENT
, name varchar(30) NOT NULL
, PRIMARY KEY (product_id) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ; 
CREATE TABLE IF NOT EXISTS product ( 
product_id int(11) NOT NULL
, size decimal(7,2) NOT NULL
, price decimal(7,2) NOT NULL
, PRIMARY KEY (product_id,size) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
INSERT INTO product (product_id, size, price) 
VALUES (1, '150', '3')
, (2, '1000', '50')
, (2, '1500', '70')
, (3, '500', '35'); 
INSERT INTO products (product_id, name) 
VALUES 
(1, 'protein-bar')
, (2, 'whey-protein')
, (3, 'casein');
product_id | name---------:|:-----------1|蛋白棒2|乳清蛋白3|酪蛋白product_id |大小|价格---------:|------:|----:1 | 150.00 | 3.002 | 1000.00 | 50.002 | 1500.00 | 70.003 | 500.00 | 35.00

db<gt;小提琴这里

我将其合并为一个,给我以下表格:

product_id |   name     |  size  | price
1        protein-bar    150       3
2        whey-protein   1000      50
2        whey-protein   1500      70
3        casein         500       35
etc...

现在,正如您所看到的,product_id不是唯一的product_id和大小

我想做的是获取用户选择的具有特定id和大小匹配的所有产品。

例如,我有以下顺序:

Array ( [1] => Array ( [Quantity] => 3 [Size] => 150) [2] => Array ( [Quantity] => 1 [Size] => 1500) )

此数组的键等于product_id。

我想做的是从数据库中提取那些用户选择的产品,我期望的输出是:

product_id |   name     |  size  | price
1        protein-bar    150       3
2        whey-protein   1500      70

为了尝试这样做,我做了以下操作:

  1. 将用户的顺序合并到一个数组中,其中第一个值是product_id,最后一个值是产品大小,得到以下数组:
Array ( [0] => 1 [1] => 2 [2] => 150 [4] => 1500)
  1. SQL语句:
$array_to_question_marks = implode(',', array_fill(0, count($products_in_cart), '?'));
$stmt = $pdo->prepare('SELECT * FROM products INNER JOIN product ON (products.product_id = product.product_id) WHERE products.product_id IN (' . $array_to_question_marks . ') AND product.size IN (' . $array_to_question_marks . ')');
$fill_question_marks = array_merge(array_keys($products_in_cart), array_column($products_in_cart, 'Size'));
$stmt->execute($fill_question_marks);

现在,它所做的是返回所有提供了id和尺寸的产品。的问题是它与产品id大小不匹配。给我以下输出:

product_id |   name     |  size  | price
1        protein-bar    150       3
2        whey-protein   1000      50
2        whey-protein   1500      70

尺寸为1000的乳清蛋白不应该在那里,因为用户没有选择它。

我几天来一直在努力解决这个问题。在这样做的时候,我得到了一个stackoverflow的答案:

SELECT * FROM table WHERE (column1, column2) IN ( (A, X), (B, Y), (C, Z) );

这似乎回答了我的问题,但我无法让它发挥作用。(这个命令可能不正确,不要把你的答案局限于它;我只是把它包括在内,以表明我为找到答案付出了很多努力,并尝试了几种方法,但都不适用(。

**这是我的第一个stackoverflow问题,试图通过使用粗体语句和代码块来使一切都清楚。以及努力遵守stackoverflow的"惯例",比如展示你的努力。这个问题已经困扰了我好几天了,我终于决定创建一个stackoverflow帐户并询问它,非常感谢您的回答。谢谢。

终于找到了解决方案。使用了@SOS和@Akina提供的SQL语句,即:

SELECT * FROM products JOIN product USING (product_id) WHERE (product_id, product.size) IN ((1, 150), (2,1500))

但由于我不知道项目/我必须从(?,?(,(?,(等形式的数组中提取它们。。我将$array_to_question_marks代码更改为以下代码:

$array_to_question_marks = implode(',', array_fill(0, count($products_in_cart), '(?, ?)'));

并使用上述变量作为SQL语句的输入,如下所示:

$stmt = $pdo->prepare('SELECT * FROM products JOIN product USING (product_id) WHERE (product_id, product.size) IN (' . $array_to_question_marks . ')');

现在,为了填充数据,我做了以下操作:

$population_array = array();
for($i=0; $i<count($products_in_cart); $i++){
array_push($population_array, array_keys($products_in_cart)[$i]);
array_push($population_array, $products_in_cart[array_keys($products_in_cart)[$i]]['Size']);
}

它推送数组键(等于product_id(,然后是与SQL语句形式匹配的形式product_id、size、product_id和size等中的相应大小。

最后,我完整的SQL命令如下:

$array_to_question_marks = implode(',', array_fill(0, count($products_in_cart), '(?, ?)'));
$stmt = $pdo->prepare('SELECT * FROM products JOIN product USING (product_id) WHERE (product_id, product.size) IN (' . $array_to_question_marks . ')');
$stmt->execute($population_array);
$products = $stmt->fetchAll(PDO::FETCH_ASSOC);

例如,我有以下顺序:

Array ( [1] => Array ( [Quantity] => 3 [Size] => 150) [2] => Array ( [Quantity] => 1 [Size] => 1500) )

此数组的键等于product_id。

SELECT *
FROM products
JOIN product USING (product_id)
WHERE (product_id, product.size) IN ((1, 150), (2,1500))

https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=e841464f422774042ae1a8ca5ba0478e

PS。我不知道应该如何应用数组的Quantity值——在源表中没有这样的列。

最新更新