Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php WHERE条件中的SQL IF ELSE/CASE子句_Php_Sql_If Statement_Switch Statement_Case - Fatal编程技术网

Php WHERE条件中的SQL IF ELSE/CASE子句

Php WHERE条件中的SQL IF ELSE/CASE子句,php,sql,if-statement,switch-statement,case,Php,Sql,If Statement,Switch Statement,Case,我有一个非常大的MySQL语句,通过php foreach循环,每个循环都连接到前面的union all。我将简化我的问题的核心陈述,如果需要,我当然也可以在以后的要求中添加更多细节 我有这张桌子 +--------+-----------+-----------+ | ID | LANG | TITLE | +--------+-----------+-----------+ | 1 | EN | T-A | +--------+-

我有一个非常大的MySQL语句,通过php foreach循环,每个循环都连接到前面的union all。我将简化我的问题的核心陈述,如果需要,我当然也可以在以后的要求中添加更多细节

我有这张桌子

+--------+-----------+-----------+
|   ID   |   LANG    |   TITLE   |
+--------+-----------+-----------+
|   1    |    EN     |   T-A     |
+--------+-----------+-----------+
|   1    |    FR     |   T-A     |
+--------+-----------+-----------+
|   2    |    FR     |   T-B     |
+--------+-----------+-----------+
|   3    |    DE     |   T-C     |
+--------+-----------+-----------+
|   3    |    EN     |   T-C     |
+--------+-----------+-----------+
我想在SQL SELECT中写一个WHERE条件,它应该为每个ID显示一个结果。但它应该只在LANG是FR或EN时显示结果。应该优先选择顶部的FR,如果ID没有可用的FR,则EN应仅显示为可选。因此,结果如下所示

+--------+-----------+-----------+
|   ID   |   LANG    |   TITLE   |
+--------+-----------+-----------+
|   1    |    FR     |   T-A     |
+--------+-----------+-----------+
|   2    |    FR     |   T-B     |
+--------+-----------+-----------+
|   3    |    EN     |   T-C     |
+--------+-----------+-----------+
我曾尝试用IF-ELSE/CASE自己构建一些东西,但我对SQL不是很有经验,所以非常感谢任何帮助

我尝试过的简化SQL类似于

SELECT * FROM `table` 
WHERE `table`.`ID` = 1
IF `table`.`LANG` = 'FR' 
BEGIN
  AND `table`.`LANG` = 'FR' 
END
ELSE
BEGIN
  AND `table`.`LANG` = 'EN' 
END

union all 
SELECT * FROM `table` 
WHERE `table`.`ID` = 2
IF `table`.`LANG` = 'FR' 
BEGIN
  AND `table`.`LANG` = 'FR' 
END
ELSE
BEGIN
  AND `table`.`LANG` = 'EN' 
END

union all 
SELECT * FROM `table` 
WHERE `table`.`ID` = 3
IF `table`.`LANG` = 'FR' 
BEGIN
  AND `table`.`LANG` = 'FR' 
END
ELSE
BEGIN
  AND `table`.`LANG` = 'EN' 
END
Sitenote我可能不会使用ORDER BY与LIMIT 1组合的任何构造,因为我会通过php多次循环SQL

编辑:对我有效的解决方案


使用复杂查询优化器的最优雅、最高效的解决方案是:

SELECT * FROM (
    SELECT * FROM `table`
    WHERE ID IN (
      SELECT id FROM `table` 
      WHERE lang = 'EN'
      EXCEPT
      SELECT id FROM `table`
      WHERE lang = 'FR'
    ) OR table.LANG ='FR'
) t1
WHERE id = ?
这将为您提供按ID过滤的所需结果。如果优化器无法向下推ID=?您可能需要自己动手才能获得良好的性能:

  SELECT * FROM `table`
    WHERE id = ? AND (ID IN (
      SELECT id FROM `table` 
      WHERE lang = 'EN' AND ID = ?
      EXCEPT
      SELECT id FROM `table`
      WHERE lang = 'FR' AND ID = ?
    ) OR table.LANG ='FR')
但是,如果可以,我将一次获得所有结果,而不是首先迭代ID:

SELECT * FROM `table`
WHERE ID IN (
  SELECT id FROM `table` 
  WHERE lang = 'EN'
  EXCEPT
  SELECT id FROM `table`
  WHERE lang = 'FR'
) OR table.LANG ='FR'
这将获得所有具有lang'EN'且没有相应的'FR'的ID加上所有的'FR'。或者,您也可以尝试:

SELECT * FROM `table`
WHERE lang = 'FR'
OR (lang = 'EN' AND ID NOT IN (SELECT ID FROM table WHERE lang = 'FR'))


但是我猜第一个查询是最快的。

你可以在你的问题中得到准确的结果,如下所示:

select * from table where lang = 'FR' union
select t_en.* from table t_en left join table t_fr 
on (t_fr.id = t_en.id and t_fr.lang = 'FR' and t_en.lang = 'EN')
where t_fr.id is null and t_en.lang = 'EN'
SELECT * FROM `table`
WHERE lang = 'FR'
OR (lang = 'EN' AND ID NOT IN (SELECT ID FROM `table` WHERE lang = 'FR'))

如果你真的想在每次你能做的时候都给出ID

SELECT * FROM `table`
WHERE (ID=1) AND
( lang = 'FR'
  OR (lang = 'EN' AND ID NOT IN (SELECT ID FROM `table` WHERE lang = 'FR'))
)
这仅为每个ID提供一个结果

您还可以使用多个ID

SELECT * FROM `table`
WHERE (ID in (1,2,3)) AND
( lang = 'FR'
  OR (lang = 'EN' AND ID NOT IN (SELECT ID FROM `table` WHERE lang = 'FR'))
)
然后根据脚本构建1,2,3并执行select。
有关mysql中case语句的更多信息,请参见。

http://dev.mysql.com/doc/refman/5.0/en/case.html
http://dev.mysql.com/doc/refman/5.0/en/if.html
为了更好地了解mysql中的if语句

http://dev.mysql.com/doc/refman/5.0/en/case.html
http://dev.mysql.com/doc/refman/5.0/en/if.html

我想知道,这是用于辅导还是在线课程?我在过去看到过非常相似的问题。OP要求的查询每个ID只返回一行。此查询不会这样做,因为外部查询可能会为内部查询中的每个ID返回多行。好的,这非常不清楚,因为他的示例表中的多行是一致的。但是很明显,这可以被包装成一个特定行的select。我认为您的第二个select确实给出了正确的结果。从lang='FR'或lang='EN'且ID不在的表中选择*从lang='FR'的表中选择ID。它为每个ID提供一个结果,除非存在具有相同语言的重复ID。请参阅。/如果必须在每个sql中指定ID,因为我从externale json_decode php脚本获取ID,因此我将测试您的上一个方案,即使它没有性能优化。您也可以首先生成所需的所有数字,并在1,2,3中使用WHERE ID。这会更快。添加了澄清条件的答案,第一次选择仅限于fr。第二次选择仅返回enOk,现在有意义了。一旦我被允许,我会尽快修正我的否决票。这仍然不能给出正确的答案。见a。您将在结果中得到一个“DE”。@Rik是的,我添加了t_en.lang='en'条件
SELECT * FROM TABLE WHERE ( LANG='FR' OR (lang='EN' AND ID NOT IN (SELECT ID FROM TABLE WHERE lang='FR' )))