Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/55.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
Mysql 如何使用AS别名以防万一_Mysql_Sql_Mariadb - Fatal编程技术网

Mysql 如何使用AS别名以防万一

Mysql 如何使用AS别名以防万一,mysql,sql,mariadb,Mysql,Sql,Mariadb,这里有一些简单的测试表和测试数据 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 I

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

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 |
+----+-----------+
让我们选择每个有性别栏的人

MariaDB [mytest]> 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;
+------+--------+
| name | gender |
+------+--------+
| Sam  | M      |
| Jim  | M      |
| Sue  | F      |
| Ida  | F      |
| Robo | X      |
+------+--------+
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 WHERE gender = 'X';
那很好。但现在我喜欢过滤关于性别的信息

MariaDB [mytest]> 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;
+------+--------+
| name | gender |
+------+--------+
| Sam  | M      |
| Jim  | M      |
| Sue  | F      |
| Ida  | F      |
| Robo | X      |
+------+--------+
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 WHERE gender = 'X';
这已经不起作用了

错误1054 42S22:“where子句”中的未知列“性别”


这里有什么问题?我用AS做了别名。它使用Sqlite,但不使用MariaDB。

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

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 WHERE 
NOT EXISTS (SELECT id FROM male WHERE male.person_id = person.id)
AND NOT EXISTS (SELECT id FROM female WHERE female.person_id = person.id)

不能从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';

与大多数数据库一样,MySQL不允许在WHERE中使用别名。但是,它确实允许HAVING子句中使用别名,并将HAVING的使用扩展到非聚合查询

所以,你可以写:

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';

至少有一个原因是MySQL在历史上总是将派生表子查询存储在临时表的FROM子句中,这会增加查询的开销。要求子查询在计算列上进行筛选代价高昂;拥有扩展是解决这个问题的一种方法。

编写有效的ANSI/ISO SQL标准代码,在同一级别的SELECT中的WHERE子句中使用别名是不允许的。请将您的查询用作子查询并应用条件。如果您不想再次键入该CASE语句的所有内容,或者您对查询优化程序没有信心,请使用子查询,例如SELECT*from SELECT name、CASE等。。从人a以性别结尾,其中a.gender='X';同样,这种模式感觉过于规范化了,分开的男性和女性表有什么意义?我同意标准化的性别表和主表中的性别id。只使用一个表,而不是3个。