Maddede Bilinmeyen Sütun


126

Basit bir sorgum var:

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

Anlıyorum Unknown Column 'user_name' in where clause. İfadenin 'user_name'diğer bölümlerine sonradan atıfta bulunamaz select 'u_name as user_name'mıyım?

Yanıtlar:


94

SQL geriye doğru, sağdan sola doğru değerlendirilir. Böylece, where cümlesi ayrıştırılır ve select cümlesinden önce değerlendirilir. Bu nedenle, u_name için kullanıcı_adı'nın takma adı henüz oluşmadı.


30
"Ters" yerine "içten dışa" demenin daha mantıklı olduğunu düşünüyorum
Joe Phillips

4
Tüm ifadenin karmaşık, çok aşamalı bir süreçte bir bütün olarak ayrıştırıldığını, dönüştürüldüğünü ve optimize edildiğini söylemek daha mantıklıdır. "SQL geriye doğru, sağdan sola doğru değerlendiriliyor" çok yanlış
David Aldridge

3
Kullanıcı, ifadede 'user_name' kullanılıp kullanılamayacağını sorduğu için eksik cevap, örneğin 'HAVING'
luke_mclachlan

45

Ne dersin:

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

16
Neden bu durumda HAVINGyerine kullanasınız WHERE?
PeteGO

4
@PeteGO, Paul Dixon'ın cevabına atıfta bulunuyor. TLDR; HAVING, WHERE ve daha da önemlisi SELECT'ten daha sonra değerlendirilir.
jairbow

38

Aşağıdaki MySQL kılavuz sayfasına bakın: http://dev.mysql.com/doc/refman/5.0/en/select.html

"Bir select_expr, AS alias_name kullanılarak bir takma ad verilebilir. Diğer ad, ifadenin sütun adı olarak kullanılır ve GROUP BY, ORDER BY veya HAVING yan tümcelerinde kullanılabilir."

(...)

Bir WHERE yan tümcesinde bir sütun diğer adına atıfta bulunulmasına izin verilmez, çünkü sütun değeri WHERE yan tümcesi yürütüldüğünde henüz belirlenmemiş olabilir. Bkz. Bölüm B.5.4.4, "Sütun Diğer Adlarıyla İlgili Sorunlar".


Ayrıca, not (MySQL adamından): SQL standardı HAVING'in yalnızca GROUP BY deyimindeki sütunlara veya toplama işlevlerinde kullanılan sütunlara başvurması gerektiğini gerektirir. Bununla birlikte, MySQL bu davranış için bir uzantıyı destekler ve ZORUNLU olarak, SELECT listesindeki sütunlara ve dış alt sorgulardaki sütunlara başvurmasına izin verir.
Vincent Pazeller

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

Bunu şöyle düşünün, where cümleniz önce hangi satırların (veya birleştirilmiş satırların) döndürülmesi gerektiğini belirlemek için değerlendirilir. Where cümlesi yürütüldüğünde, select cümlesi onun için çalışır.

Daha iyi bir şekilde ifade etmek için şunu hayal edin:

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

İkincisi olmadan ilk yarıyı referans alamazsınız. Her zaman önce nerede değerlendirilir, ardından select cümlesi.


11

Veritabanında gerçekte mevcut olmayan yeni bir alan oluşturmak için bir SELECT ifadesi kullandığınız ve aşağıdaki gibi bir sorgu gerçekleştirmeye çalışıyorsanız (en az bir eke sahip tüm düğümleri bulun) ve kullanmayı deneyin bu sonucun takma adı, aynı problemle karşılaşacaksınız:

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

WHERE yan tümcesinde "Bilinmeyen sütun 'ek sayısı' hatası alırsınız.

Çözüm aslında oldukça basittir - sadece takma adı, diğer adı üreten ifadeyle değiştirin, örneğin:

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;

Yine de döndürülen takma adı alacaksınız, ancak artık SQL bilinmeyen takma adla çalışmamalıdır.


1
Tam olarak bu problemle karşı karşıyaydım ve cevabınızla karşılaştım - teşekkür ederim! Sadece not etmek gerekirse, büyük veritabanlarında biraz yavaş (anlaşılır bir şekilde), ancak yine de aptal bir miras alınan veritabanı kurulumuyla uğraşıyorum.
Liam Newmarch

(Sorgunuzda (COUNT(*)herhangi bir yerde kapatılmayan fazladan bir şey olduğuna inanıyorum .
tftd

3
Ancak SELECT ifadesi iki kez çalıştırılmaz mı?
Matej

Şu ana kadar mysql uzmanı değilim ama bu çok yetersiz görünüyor. İç içe geçmiş seçimlerin sorguyu çok daha yavaş yaptığını deneyimledim.
GDY

8

Tanımladığınız madde, bunun için maddeyi kullanmak zorunda olduğunuz madde aliastarafından hoş karşılanmazWHEREHAVING

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

VEYA orijinal sütun adını doğrudan WHERE

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

Alt sorgu veya herhangi bir hesaplama sonucunda kullanıcı tanımlı takma adla sonuç almanızla aynı şekilde 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

Ya:

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

veya:

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

RDBMS koşulu satır içi görünüme itmeyi destekliyorsa, ikincisi öncekiyle aynı olmalıdır.





1

WHEREMadde 1 ve 2'nin neden olduğu ve 3. satır tarafından çözülen bilinmeyen sütun :

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

Neyi değiştirdin ve neden? Ek olarak, neden SQL enjeksiyonları için geniş ölçüde açık olan bir kod gönderdiniz?
Nico Haase

1

Yardımcı olabilir.

Yapabilirsin

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

İşe yarıyor.

ANCAK NE YAPTIĞINIZDAN EMİN OLUN!

  • Dizinler burada KULLANILMAZ
  • TAM TABLO taranacak - SINIR 1 bölümünü belirtmediniz
  • Öyleyse, - BU SORGU büyük masalarda ÇOK ÇOK ÇOK OLACAK.

Ancak, bazı durumlarda yardımcı olabilir


0

Sorgunuzdaki tablolarınıza takma ad verebilirsiniz (örneğin, "Kullanıcılardan u.kullanıcı adını SEÇİN u;"), referans verdiğiniz sütunların gerçek adlarını kullanmanız gerekir. AS yalnızca alanların nasıl döndürüleceğini etkiler.


Örneğin MySql gibi bazı RDBMS'de takma adı kullanabileceğinizi düşünüyorum. Yine de Sql Server için haklısınız.
PeteGO

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

Neden bir alt sorgu kullanmak istersiniz? Olmadan çok daha basit.
PeteGO

0

Sadece bu sorunu yaşadım.

Veritabanındaki varlığın adında boşluk olmadığından emin olun.

örneğin, "kullanıcı_adı" yerine "kullanıcı_adı"


-1

IN koşulunu veya OR koşulunu kullanarak görevinizi deneyin ve ayrıca bu sorgu spark-1.6.x üzerinde çalışıyor

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

veya

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

-1

Benim için sorunun kökü, bir WHERE yan tümcesinde kullanmak için kopyaladığım bir sayıydı. Numarada "görünmez" sembolü vardı, en azından MySQL Workbench için. Numarayı Chrome konsoluna yerleştirdim, açıkça görülüyordu.


-2

Ben de aynı sorunu yaşadım, bunu faydalı buldum.

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

$ user'ı tek tırnak içine '' koymayı unutmayın.


1
Bu kod, SQL enjeksiyonu için oldukça açıktır. Verilen sorunu çözmek için kimse bu kodu kullanmamalıdır
Nico Haase
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.