2017-08-18 60 views
-3

我想在SQL語句中聲明一個變量以在下一行中使用它。我寫了一個簡單的陳述作爲例子:在SQL語句中生成變量

SELECT customer.surname, LENGTH(customer.name) long, customer.age 
FROM customer 
WHERE long > 4; 

我沒有在網上發現任何「清除」信息,甚至有可能嗎?

+1

這並不是很清楚你要做什麼。請提供更多信息。什麼是你想要的變量類型,你想分配給它在'下一行'中使用什麼? –

+1

'Where length(customer.name)> 4.'由於[操作順序](https://www.bennadel.com/blog/70),長別名(不是一個變量但是關閉) -SQL-查詢訂單的-operations.htm)。從,然後在那裏選擇。所以首先數據庫從客戶那裏獲取記錄。然後它將它們限制爲4,然後顯示選擇值和計算值。按照這個順序,你可以看到當執行where子句時long不會被知道。 – xQbert

+0

您的標題顯示「VARIABLE」,但在您的SQL語句中,「long」是別名。這些是SQL中的不同概念,導致您的問題含糊不清。我假設你的意思是別名而不是變量。沒有什麼大不了的,只是想讓你意識到不同之處;所以我們可以消除問題中的不明確性。 – xQbert

回答

0

你在網上搜索過嗎?這個字面意思是無處不在......這可能是這樣的;

DECLARE aVariable NUMBER; 

BEGIN 
    SELECT someColumn INTO aVariable FROM aTable; 
END; 
+1

我不確定這是他們以後的樣子;但問題不明確。標題基本上是你的答案,但提出的SQL意味着不同的東西。 – xQbert

1

雖然在SQL中有問題的解決方案,但您提問的方式不正確。

SELECT * 
    FROM (SELECT customer.surname, 
       LENGTH (customer.name) col_long, 
       customer.age 
      FROM customer) 
WHERE col_long > 4; 

子查詢在這裏被稱爲in-line視圖。有關更多信息,請在線查看Oracle文檔。

另外,LONG是一個保留關鍵字,所以要麼重命名它,要麼使用「long」。

2

select語句的操作順序與寫入順序不同。

  1. 起(含聯接和子查詢,但隨後在操作的順序重新開始的子查詢;就像代數運算順序;內而外)
  2. WHERE
  3. GROUP BY
  4. 選擇
  5. HAVING
  6. ORDER BY

有一些例外以上並不是所有的引擎都以這種方式處理。如果你使用的是mySQL,你可能可以在一個組中使用別名。我並不熟悉它是否會改變處理過程,或者mySQL只是在向前看。

按照這個順序,您可以看到在生成'long'別名之前執行的位置,因此數據庫引擎不知道它在執行時的長度。換句話說,在where子句被評估時,long不在範圍內。

這可以通過簡單地重複where子句中的計算或嵌套查詢來解決;但後者效率較低。

在下面的我:

  • 別名客戶爲c,以節省打字和提高可讀性。
  • 重寫了where子句以使用公式代替別名
  • 由於reserved/keyword的使用而重命名了您的長別名。

SELECT c.surname, LENGTH(customer.name) as Name_Len, c.age 
FROM customer as c 
WHERE LENGTH(c.name)> 4; 

在接下來的例子中我們使用with鍵字以生成與計算出的名稱的長度的一組稱爲CTE的數據(公用表表達式)。這實際上改變了處理where子句的順序。

在這種情況下,在CTE中處理FROM,然後選擇包括我們的計算值,但不應用where子句。然後運行第二個查詢,使用where子句從CTE數據集中選擇。由於第一個數據集已經計算出了Name_Len,我們現在可以在where子句中使用它。

WITH CTE AS (SELECT c.surname, LENGTH(customer.name) as Name_Len, c.age 
    FROM customer as c) 
SELECT * 
FROM CTE  
WHERE Name_Len > 4; 

這也可以作爲一個子查詢進行;但是在嵌套其中的一些之後,可以看到使用with可能會使讀取/維護更加容易。

SELECT CTE.* 
FROM (SELECT c.surname, LENGTH(customer.name) as Name_Len, c.age 
     FROM customer as c) as CTE  
WHERE CTE.Name_Len > 4;