如何在CASE中使用AS别名

时间:2019-07-30 16:00:04

标签: mysql sql mariadb

这里有一些带有测试数据的简单测试表。

Activity

看看。

@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int pos, long id) {
    String newLang = adapterView.getItemAtPosition(pos).toString();
    Log.e(TAG, "onItemSelected: " + newLang);

    Locale currentLocale = LocaleHelper.getLocale(getResources().getConfiguration());
    Locale newLocale = new Locale(newLang);
    if (!currentLocale.getLanguage().equalsIgnoreCase(newLocale.getLanguage())) {
        Log.e(TAG, String.format("Changing language from %s to %s", currentLocale.getLanguage(), newLocale.getLanguage()));
        LocaleHelper.setLocale(this, newLang);
        Log.d(TAG, "Recreating activity");
        recreate();
    }
}

@Override
protected void attachBaseContext(Context newBase) {
    Log.d(TAG, "attachBaseContext");
    String lang = LocaleHelper.getLanguage(newBase);
    Log.e(TAG, "attachBaseContext::setting language::" + lang);
    super.attachBaseContext(CustomContextWrapper.wrap(newBase, lang));
}

让每个人选择带有性别列的人。

CREATE DATABASE mytest;
USE mytest;

CREATE TABLE person (id INTEGER, name VARCHAR (10));
CREATE TABLE male (id INTEGER AUTO_INCREMENT, person_id INTEGER, PRIMARY KEY (id));
CREATE TABLE female (id INTEGER AUTO_INCREMENT, person_id INTEGER, PRIMARY KEY (id));

INSERT INTO person (id, name) VALUES (1, "Sam");
INSERT INTO male (person_id) VALUES (1);
INSERT INTO person (id, name) VALUES (2, "Jim");
INSERT INTO male (person_id) VALUES (2);
INSERT INTO person (id, name) VALUES (3, "Sue");
INSERT INTO female (person_id) VALUES (3);
INSERT INTO person (id, name) VALUES (4, "Ida");
INSERT INTO female (person_id) VALUES (4);
INSERT INTO person (id, name) VALUES (5, "Robo");

那很好。但是现在我想过滤性别。

MariaDB [mytest]> SELECT * FROM person;
+------+------+
| id   | name |
+------+------+
|    1 | Sam  |
|    2 | Jim  |
|    3 | Sue  |
|    4 | Ida  |
|    5 | Robo |
+------+------+


MariaDB [mytest]> SELECT * FROM male;
+----+-----------+
| id | person_id |
+----+-----------+
|  1 |         1 |
|  2 |         2 |
+----+-----------+

MariaDB [mytest]> SELECT * FROM female;
+----+-----------+
| id | person_id |
+----+-----------+
|  1 |         3 |
|  2 |         4 |
+----+-----------+

那不再起作用了。

  

错误1054(42S22):“ where子句”中的未知列“ gender”

这是什么问题?我用AS做别名。它可用于Sqlite,但不适用于MariaDB。

3 个答案:

答案 0 :(得分:2)

您不能在WHERE子句中引用SELECT子句中的别名,但可以使用子查询或CTE:

-- Subquery
SELECT * 
FROM (
  SELECT name, CASE  
      WHEN EXISTS (SELECT id FROM male WHERE male.person_id = person.id) THEN 'M'  
      WHEN EXISTS (SELECT id FROM female WHERE female.person_id = person.id) THEN 'F'  
      ELSE 'X' END AS gender 
  FROM person 
) as subqry
WHERE gender = 'X';

-- CTE
WITH cte AS (
  SELECT name, CASE  
      WHEN EXISTS (SELECT id FROM male WHERE male.person_id = person.id) THEN 'M'  
      WHEN EXISTS (SELECT id FROM female WHERE female.person_id = person.id) THEN 'F'  
      ELSE 'X' END AS gender 
  FROM person 
)
SELECT * 
FROM cte
WHERE gender = 'X';

答案 1 :(得分:1)

如果稍微改变一下,您可以获得相同的结果

timestamp

答案 2 :(得分:1)

MySQL(与大多数数据库一样)不允许$this->user>->hasPermission( 'modify', extension/extension); 中使用别名。但是,它确实在WHERE子句中允许使用别名,并将HAVING的使用范围扩展到非聚合查询。

因此,您可以编写:

HAVING

造成这种情况的至少一个原因是因为(从历史上来看,一直以来)MySQL将派生表(SELECT name, CASE (CASE WHEN EXISTS (SELECT id FROM male WHERE male.person_id = person.id) THEN 'M' WHEN EXISTS (SELECT id FROM female WHERE female.person_id = person.id) THEN 'F' ELSE 'X' END) AS gender FROM person HAVING gender = 'X'; 子句中的子查询)存储在临时表中-这增加了查询的开销。需要一个子查询来对计算列进行过滤是很昂贵的。 FROM扩展名是解决此问题的一种方法。