如何通过两个AND条件过滤一列?

时间:2019-12-24 17:36:17

标签: php mysql sql where-clause

问题已解决。但是,如果您有“更好”的方法或其他方法,请随时添加评论!谢谢大家的阅读! :)

我正在尝试进行动态查询。除了一件事,一切都运转良好。我已经在Google待了几天,但我不知道该如何完成以下工作;

SELECT project.name, project.description, track.name, track.description
   , SDG.position, SDG.title, SDG.description
   , sprint_numbers.number, sprint_options.option
   , resources.name, resources.description
   , URLs.URL 
FROM project INNER JOIN track ON project.track_id = track.id 
INNER JOIN project_SDG ON project.id = project_SDG.project_id 
INNER JOIN SDG ON project_SDG.SDG_id = SDG.id
INNER JOIN sprint ON sprint.project_id = project.id 
INNER JOIN sprint_numbers ON sprint_numbers.id = sprint.sprint_number_id 
INNER JOIN sprint_options ON sprint_options.id = sprint.sprint_option_id 
INNER JOIN resources ON project.id = resources.project_id 
INNER JOIN URLs ON URLs.id = resources.id 
WHERE 1=1 
   AND MATCH (project.name) AGAINST (:name_project) 
   AND MATCH (project.description) AGAINST (:description_project) 
   AND SDG.id = :SDG_1 
   AND SDG.id = :SDG_2

查询执行但不返回任何内容。问题是SDG.id不能同时对:SDG_1和:SDG_2都是正确的。

使用OR运算符可以工作,但这并不能以我想要的方式返回它。它必须“充当” AND运算符。 (:SDG_1和:SDG_2是绑定到SQL语句参数的PHP变量的名称。)

查询应过滤两个值。指定给:SDG_1和:SDG_2的值都必须存在于project_SDG表的SDG.id列中。如果:SDG_1的值存在,但:SDG_2的值不存在,则查询不应返回任何内容。

我在StackOverflow上找到了这个,但对我不起作用:SELECTING with multiple WHERE conditions on same column

我希望有人能帮助我。

编辑:可重复的最小示例

查询:

SELECT * FROM project
INNER JOIN project_SDG ON project.id = project_SDG.project_id 
INNER JOIN SDG ON project_SDG.SDG_id = SDG.id
WHERE SDG.id = 1 AND SDG.id = 7 AND SDG.id = 14 AND SDG.id = 17

项目表

+------------------+---------------------------+------------+
|     id  name     |        description        |  track_id  |
+------------------+---------------------------+------------+
| 1   project name | This is a description   2 |            |
+------------------+---------------------------+------------+

SDG表

+-----+-----------+-------------+---------------------------------------------+
| id  | position  |   title     |                 description                 |
+-----+-----------+-------------+---------------------------------------------+
|   1 |         1 | SDG 1 to 17 | There're multiple SDGs ranging from 1 to 17 |
|  17 |        17 | SDG 1 to 17 | There're multiple SDGs ranging from 1 to 17 |
+-----+-----------+-------------+---------------------------------------------+

project.SDG(桥表)

+------------+--------+
| project.id | SDG.id |
+------------+--------+
|          1 |      1 |
|          1 |      2 |
|          1 |      3 |
+------------+--------+

3 个答案:

答案 0 :(得分:0)

您能否为查询提供minimal reproducible example
一般来说,一个字段不能同时等于两个不同的值。因此,您要么混淆了逻辑运算符,要么需要两个不同的字段。

我可以假设您的情况下可能有多个具有不同值的相关记录。在这种情况下,您需要使用不同的别名两次连接同一张表。假设为<div class="row" v-for="(row, index) in myArray" :data-row="index" :key="index"> <div class="item" v-for="(item, subindex) in row" :data-item="index*row.length+subindex" v-bind:key="subindex"></div> </div> SDG1。之后,您可以比较

SDG2

更新

获胜诀窍正在分组。您可以枚举所有必需的SDG ID,并计算其中有多少个。仅以两个ID为例:

... `SDG1`.id = :SDG_1 AND `SDG2`.id = :SDG_2

在此处查看我的沙盒:https://www.db-fiddle.com/f/pixe3Zcs75Mq2PyCYPk913/0

如果需要所有项目的字段,则必须将其作为子查询放入

SELECT project.id
FROM project
JOIN project_SDG ON project_SDG.project_id = project.id
JOIN SDG ON SDG.id = project_SDG.SDG_id
WHERE SDG.id IN(1,2)
GROUP BY project.id
HAVING COUNT(*) = 2

子查询示例:https://www.db-fiddle.com/f/pixe3Zcs75Mq2PyCYPk913/1

答案 1 :(得分:0)

您希望每个project.id的值:SDG_1:SDG_2对于SDG.id同时存在,因此请在WHERE子句中使用它:

WHERE 1=1 
    AND MATCH (project.name) AGAINST (:name_project) 
    AND MATCH (project.description) AGAINST (:description_project) 
    AND project.id IN (
        SELECT project_id
        FROM project_SDG
        WHERE SDG_id IN (:SDG_1, :SDG_2)
        GROUP BY project_id
        HAVING COUNT(DISTINCT SDG_id) = 2
    ) 

答案 2 :(得分:0)

我已经在这里回答了,但是我有另一个方法。

1。查找与某个项目相关的一堆ID

要找到项目ID,我们可以测试没有任何连接的孤独数据透视表

  SELECT project_id FROM project_SDG
  WHERE SDG_id IN(1,2,6)
  GROUP BY project_id HAVING COUNT(*) = 3

它为我们提供了项目ID列表

2。访问所有项目字段并添加其他条件

SELECT project.*
FROM project
JOIN (
  SELECT project_id FROM project_SDG
  WHERE SDG_id IN(1,2,6)
  GROUP BY project_id HAVING COUNT(*) = 3
) AS ids ON ids.project_id = project.id
WHERE
  MATCH(project.name) AGAINST ('project') AND
  MATCH(project.description) AGAINST ('sit')

您可以在这里使用它:https://www.db-fiddle.com/f/pixe3Zcs75Mq2PyCYPk913/3

3。在PHP端准备查询

我将使用known technique来准备SQL语句。

$ids = [1, 2, 6]; // it can come from request parameters
$text1 = 'project';
$text2 = 'sit';
// build ?,?,?,... pattern
$qmarks = implode(',', array_fill(0, count($ids), '?'));
// Use SQL query above
$sth = $dbh->prepare("
SELECT project.*
FROM project
JOIN (
  SELECT project_id FROM project_SDG
  WHERE SDG_id IN({$qmarks})
  GROUP BY project_id HAVING COUNT(*) = ?
) AS ids ON ids.project_id = project.id
WHERE
  MATCH(project.name) AGAINST (?) AND
  MATCH(project.description) AGAINST (?)
");
$sth->execute(array_merge($ids, [count($ids), $text1, $text2]));
$records = $sth->fetchAll();