Where 절의 알 수없는 열


126

간단한 쿼리가 있습니다.

SELECT u_name AS user_name FROM users WHERE user_name = "john";

나는 Unknown Column 'user_name' in where clause. 'user_name'이후에도 성명서의 다른 부분에서 언급 할 수 없습니까 select 'u_name as user_name'?

답변:


94

SQL은 오른쪽에서 왼쪽으로 거꾸로 평가됩니다. 따라서 where 절은 select 절 이전에 구문 분석되고 평가됩니다. 이 때문에 u_name에서 user_name으로의 별칭이 아직 발생하지 않았습니다.


30
"뒤로"보다는 "안쪽으로"라고 말하는 것이 더 합리적이라고 생각합니다
Joe Phillips

4
전체 문이 복잡한 다단계 프로세스에서 전체적으로 구문 분석, 변환 및 최적화되었다고 말하는 것이 더 합리적입니다. "SQL은 오른쪽에서 왼쪽으로, 뒤쪽으로 평가한다"단지 잘못된
데이비드 드리지

3
'_ 이름은'가 'HAVING'예 후 될 수있는 문에서 사용할 수있는 경우 사용자 불완전 대답은 질문
luke_mclachlan

45

이건 어떤가요:

SELECT u_name AS user_name FROM users HAVING user_name = "john";

16
이 경우 HAVING대신 사용 하는 이유는 무엇 WHERE입니까?
PeteGO 2014

4
@PeteGO는 Paul Dixon의 답변을 참조하십시오. tldr; HAVING은 WHERE보다 나중에 평가되며 더 중요한 것은 SELECT입니다.
jairbow

38

다음 MySQL 매뉴얼 페이지를 참조하십시오. http://dev.mysql.com/doc/refman/5.0/en/select.html

"select_expr은 AS alias_name을 사용하여 별칭을 부여 할 수 있습니다. 별칭은 표현식의 열 이름으로 사용되며 GROUP BY, ORDER BY 또는 HAVING 절에서 사용할 수 있습니다."

(...)

WHERE 절이 실행될 때 열 값이 아직 결정되지 않았을 수 있으므로 WHERE 절에서 열 별칭을 참조하는 것은 허용되지 않습니다. B.5.4.4 절.“열 별칭 문제”를 참조하십시오.


또한 (MySQL man의) 참고 : SQL 표준에서는 HAVING이 GROUP BY 절의 열 또는 집계 함수에 사용되는 열만 참조해야합니다. 그러나 MySQL은이 동작에 대한 확장을 지원하고 HAVING이 SELECT 목록의 열과 외부 하위 쿼리의 열을 참조하도록 허용합니다.
Vincent Pazeller 17 년

12
select u_name as user_name from users where u_name = "john";

반환해야 할 행 (또는 조인 된 행)을 결정하기 위해 where 절이 먼저 평가됩니다. where 절이 실행되면 select 절이 실행됩니다.

더 나은 방법으로 말하면 다음과 같이 상상해보십시오.

select distinct(u_name) as user_name from users where u_name = "john";

두 번째없이 전반을 참조 할 수 없습니다. 항상 먼저 평가되는 곳은 select 절입니다.


11

SELECT 문을 사용하여 데이터베이스에 실제로 존재하지 않는 새 필드를 만든 다음과 같은 쿼리를 수행하려는 경우 (적어도 하나의 첨부 파일이있는 모든 노드를 찾고) 그 결과에 대한 별칭은 동일한 문제가 발생합니다.

SELECT nodes.*, (SELECT (COUNT(*) FROM attachments 
WHERE attachments.nodeid = nodes.id) AS attachmentcount 
FROM nodes
WHERE attachmentcount > 0;

"WHERE 절에서 알 수없는 'attachmentcount'열"이라는 오류가 발생합니다.

솔루션은 실제로 매우 간단합니다. 별칭을 생성하는 문으로 별칭을 바꾸십시오. 예 :

SELECT nodes.*, (SELECT (COUNT(*) FROM attachments 
WHERE attachments.nodeid = nodes.id) AS attachmentcount 
FROM nodes 
WHERE (SELECT (COUNT(*) FROM attachments WHERE attachments.nodeid = nodes.id) > 0;

여전히 별칭이 반환되지만 이제 SQL은 알 수없는 별칭에서 지루하지 않아야합니다.


1
나는이 정확한 문제에 직면했고 당신의 대답을 발견했습니다-감사합니다! 참고로 큰 데이터베이스에서는 (이해할 만하게) 약간 느리지 만 어쨌든 어리석은 상속 된 데이터베이스 설정을 다루고 있습니다.
Liam Newmarch 2011 년

나는 당신이 어디에도 닫히지 않는 (전에 당신의 쿼리에 여분이 있다고 믿습니다 (COUNT(*).
tftd

3
그러나 SELECT 문이 두 번 실행되지 않습니까?
Matej

나는 지금까지 mysql 전문가는 아니지만 이것은 매우 부적절한 것 같습니다. 중첩 된 선택이 쿼리를 훨씬 느리게 만드는 것을 경험했습니다.
GDY

8

귀하의 정의 alias는 이에 대한 WHERE조항을 사용해야하는 HAVING조항에 의해 환영받지 않습니다.

SELECT u_name AS user_name FROM users HAVING user_name = "john";

또는 원래 열 이름을 WHERE

SELECT u_name AS user_name FROM users WHERE u_name = "john";

하위 쿼리 또는 계산의 결과로 사용자 정의 별칭에 결과가있는 것과 동일 HAVING합니다.WHERE

SELECT u_name AS user_name ,
(SELECT last_name FROM users2 WHERE id=users.id) as user_last_name
FROM users  WHERE u_name = "john" HAVING user_last_name ='smith'

7

어느 한 쪽:

SELECT u_name AS user_name
FROM   users
WHERE  u_name = "john";

또는:

SELECT user_name
from
(
SELECT u_name AS user_name
FROM   users
)
WHERE  u_name = "john";

후자는 RDBMS가 인라인보기로 푸시하는 술어를 지원하는 경우 전자와 동일해야합니다.



5

정확한 이름으로 선택할 필요가 없습니다. 별칭에서 선택한 테이블을 제공하면 사용할 수 있습니다.


2

아니 당신은 할 수 없습니다. user_name은 반환 시간까지 존재하지 않습니다.


1

WHERE1 행과 2 행에 의해 발생하고 3 행에 의해 해결 된 절의 알 수없는 열

  1. $sql = "SELECT * FROM users WHERE username =".$userName;
  2. $sql = "SELECT * FROM users WHERE username =".$userName."";
  3. $sql = "SELECT * FROM users WHERE username ='".$userName."'";

무엇을 변경했으며 그 이유는 무엇입니까? 또한 SQL 주입을 위해 널리 공개 된 코드를 게시 한 이유는 무엇입니까?
Nico Haase

1

도움이 될 수 있습니다.

당신은 할 수 있습니다

SET @somevar := '';
SELECT @somevar AS user_name FROM users WHERE (@somevar := `u_name`) = "john";

효과가있다.

그러나 당신이 무엇을하는지 확인하십시오!

  • 여기서 색인은 사용되지 않습니다.
  • FULL TABLE이 스캔됩니다-LIMIT 1 부분을 지정하지 않았습니다.
  • 따라서-이 쿼리는 거대한 테이블에서 느리게 처리됩니다.

그러나 어떤 경우에는 도움이 될 수 있습니다.


0

쿼리 내에서 테이블 별칭을 지정할 수 있지만 (예 : "SELECT u.username FROM users u;") 참조하는 열의 실제 이름을 사용해야합니다. AS는 필드가 반환되는 방식에만 영향을줍니다.


예를 들어 MySql과 같은 일부 RDBMS에서 별칭을 사용할 수 있다고 생각합니다. 그래도 SQL Server에 맞습니다.
PeteGO 2014

0
SELECT user_name
FROM
(
SELECT name AS user_name
FROM   users
) AS test
WHERE  user_name = "john"

하위 쿼리를 사용하려는 이유는 무엇입니까? 없이 훨씬 간단합니다.
PeteGO 2014

0

이 문제가있었습니다.

데이터베이스의 엔티티 이름에 공백이 없는지 확인하십시오.

예 : 'user_name'대신 'user_name'


-1

IN 조건 또는 OR 조건을 사용하여 작업을 시도 하고이 쿼리는 spark-1.6.x에서 작동합니다.

 SELECT  patient, patient_id FROM `patient` WHERE patient IN ('User4', 'User3');

또는

SELECT  patient, patient_id FROM `patient` WHERE patient = 'User1' OR patient = 'User2';

-1

나에게 문제의 근원은 WHERE 절에서 사용하기 위해 복사 한 숫자였습니다. 이 숫자는 최소한 MySQL Workbench의 경우 "보이지 않는"기호를 가졌습니다. Chrome 콘솔에 번호를 배치했는데 명확하게 표시되었습니다.


-2

나는 같은 문제가 있었고 이것이 유용하다는 것을 알았습니다.

mysql_query("SELECT * FROM `users` WHERE `user_name`='$user'");

$ user를 ''작은 따옴표로 묶는 것을 잊지 마십시오.


1
이 코드는 SQL 주입을 위해 널리 공개되어 있습니다. 아무도는 주어진 문제를 해결하기 위해이 코드를 사용해서는 안
니코 하세
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.