2013-04-09 78 views
7

我需要創建一個名爲row_num的視圖,其中它將插入行號,就像普通表中的自動增量一樣。使用列創建視圖num_rows - MySQL

我真的很新,所以請與我一起裸露。 比方說,我有這個普通表:

| country | name | age | price | 
-------------------------------- 
| US  | john | 22 | 20 | 
| France | Anne | 10 | 15 | 
| Sweden | Alex | 49 | 10 | 

等等......

我想創造的觀點是:

| country | name | price | row_num | 
    ------------------------------------ 
    | US  | john | 20 | 1 | 
    | France | Anne | 10 | 2 | 
    | Sweden | Alex | 5 | 3 | 

等等...

我可以用單個select生成row_num:

SELECT @i:[email protected]+1 AS row_num, testing.country, testing.name, testing.price 
FROM testing testing,(SELECT @i:=0) derivedTable 
order by name 

但我的問題是將上面的查詢與創建視圖的查詢結合起來。 這是組合查詢我想:

CREATE OR REPLACE view vwx (country, name, price, num_row) AS SELECT mytable.country, mytable.name, mytable.price, @i:[email protected]+1 AS row_number 
    FROM testing testing,(SELECT @i:=0) derivedTable 
    order by name; 

我得到以下錯誤:#1351 - 視圖的SELECT語句包含變量或參數

我知道我不能用一個選擇內選擇有意見,但我沒有看到其他方式來做我想要的方式,但我相信有一種方法可以做到這一點,但我只是不知道如何。可能與功能或程序,但我真的很陌生,所以我不習慣在mysql中創建函數或過程。

我希望自己明確了,否則我很樂意更詳細地解釋自己。

+1

爲什麼沒有像你可以使用的「普通表」那樣的自動增量? – Neal 2013-04-09 01:53:52

+0

因爲我沒有設計該表,並且該表已經存儲了數千和數千條記錄。另外他們不允許我在桌子上改變任何東西,這就是我使用視圖的原因。 – dazito 2013-04-09 01:58:54

+0

啊,還有一個我忘記提到的@Neal細節是視圖是用where子句創建的,我沒有把它放在那裏,因爲我認爲它不是一個重要的細節。 – dazito 2013-04-09 02:21:00

回答

5

我找到了一個解決方案:您要開始用數字

delimiter // 

CREATE FUNCTION `func_inc_var_session`() RETURNS int 
    NO SQL 
    NOT DETERMINISTIC 
    begin 
     SET @var := @var + 1; 
     return @var; 
    end 
    // 

delimiter ; 

然後設置@var:

首先創建一個函數。 在這種情況下爲零。

SET @var=0;

然後創建視圖如下:

CREATE OR REPLACE VIEW myview (place, name, hour, price, counter) 
AS SELECT place, name, hour, price, func_inc_var_session() 
FROM yourtable 
WHERE input_conditions_here; 

這裏的技巧是,你可能會看到空的計數器列。如果發生這種情況,請將@var再次設置爲您的號碼,然後再次執行SELECT *,您會看到正確填充了計數器列。

+0

當我這樣做時,通過「input_conditions_here」中的「order by」,我以錯誤的順序獲取func_inc_var_session()。我認爲這裏需要一個子查詢。 – user43326 2018-01-14 17:18:37

-1
CREATE OR REPLACE view vwx (country, name, price, num_row) AS 
SELECT country, name, price, @index := @index + 1 AS num_row 
FROM testing, (SELECT @index := 0) temp 
+4

這是不可能的我害怕因爲它在創建視圖上使用了一個變量,所以我得到和以前一樣的錯誤:'錯誤代碼:1351.視圖的SELECT包含一個變量或參數\t 0.000秒' – dazito 2013-04-10 13:28:56

0

嘗試此查詢適用於您的觀點 -

CREATE TABLE testing (
    id int(11) NOT NULL DEFAULT 0, 
    country varchar(255) DEFAULT NULL, 
    name varchar(255) DEFAULT NULL, 
    age int(11) DEFAULT NULL, 
    price int(11) DEFAULT NULL, 
    PRIMARY KEY (id) 
); 

INSERT INTO testing(id, country, name, age, price) VALUES 
    (1, 'US', 'john', 22, 20), 
    (2, 'France', 'Anne', 10, 15), 
    (3, 'Sweden', 'Alex', 49, 10), 
    (4, 'France', 'Anne', 11, 16); 

SELECT 
    t1.*, COUNT(*) row_num 
FROM testing t1 
    LEFT JOIN testing t2 
    ON t2.name < t1.name OR (t2.name = t1.name AND t2.id <= t1.id) 
GROUP BY t1.name, t1.id; 

+----+---------+------+------+-------+---------+ 
| id | country | name | age | price | row_num | 
+----+---------+------+------+-------+---------+ 
| 3 | Sweden | Alex | 49 | 10 |  1 | 
| 2 | France | Anne | 10 | 15 |  2 | 
| 4 | France | Anne | 11 | 16 |  3 | 
| 1 | US  | john | 22 | 20 |  4 | 
+----+---------+------+------+-------+---------+ 
  • 此查詢不使用任何用戶變量,所以它的觀點wotks。
  • ON子句中的附加條件有助於在name字段中實現重複的值。
+0

在你的第5行,其中你有'ON t2.name dazito 2013-04-10 13:49:36

+0

哦,對不起。我的意思是唯一的ID列。我將添加完整的示例。 – Devart 2013-04-10 14:05:19

1

或者試試這個 - >創建一個臨時表,並插入您的數據到它像波紋管

CREATE OR REPLACE TEMPORARY TABLE myview (
    country VARCHAR(250), 
    name VARCHA(50), 
    price VARCHAR(50), 
    row_num int(11) 
); 

SET @row_num = 0; 
INSERT INTO myview (country,name,price,row_num) 
    SELECT @row_num:[email protected]_num+1 
     as country,name,price,row_num 
    FROM testing; 

SELECT * FROM myview; 

+---------+------+------+-------+---------+ 
| country | name | age | price | row_num | 
+---------+------+------+-------+---------+ 
| Sweden | Alex | 49 | 10 |  1 | 
| France | Anne | 10 | 15 |  2 | 
| France | Anne | 11 | 16 |  3 | 
| US  | john | 22 | 20 |  4 | 
+---------+------+------+-------+---------+ 
2

我試過func_inc_var_session函數的例子。

有一個會話變量初始化的小問題,我使用mysql IFNULL函數解決。

下面增強func_inc_var_session函數。

CREATE DEFINER=`root`@`localhost` FUNCTION `func_inc_var_session`() RETURNS int(11) 
begin 
    SET @var := IFNULL(@var,0) + 1; 
    return @var; 
end 
+1

請注意:如果您在單個查詢中使用了函數兩次或更多次(例如使用JOIN),它將繼續增加變量。 – 2017-09-07 11:57:28

0

添加行號查詢結果 - 無需查看 - 一個查詢

SELECT country, name, price, @ID := @ID + 1 AS row_num 
FROM testing, 
    (SELECT @ID := 0) temp 

以下內容添加到你的MySQL的connectionString:Allow User Variables=True;

不要添加「十字在您的查詢中加入「以更新您的@ID變量。

+0

歡迎來到SO。正確格式化你的答案中的代碼是非常有用的:-) – Blackbam 2017-03-07 20:42:28

+0

OP想要得到的結果作爲一個視圖,你的答案不會作爲視圖。 – user43326 2018-01-14 17:15:51

1

從@dazito使用解決方案時,可能會遇到計數器不斷從查詢增加到查詢的問題,例如應用程序重新使用會話時(例如使用JPA/Hibernate)。例如:

查詢1:

 
| country | name | price | row_num | 
------------------------------------ 
| US  | john | 20 | 1 | 
| France | Anne | 10 | 2 | 
| Sweden | Alex | 5 | 3 | 

問題2:

 
| country | name | price | row_num | 
------------------------------------ 
| US  | john | 20 | 4 | 
| France | Anne | 10 | 5 | 
| Sweden | Alex | 5 | 6 | 

一種解決方法是加入與(一次性)的主查詢調用計數器函數並對函數進行參數化(下面的「重置」參數),讓它知道這是第一次調用。

 
delimiter // 
CREATE FUNCTION `func_inc_var_session`(reset BIT) RETURNS int 
    NO SQL 
    NOT DETERMINISTIC 
    begin 
     IF reset THEN 
     SET @var := 0; 
     ELSE 
     SET @var := IFNULL(@var,0) + 1; 
     END IF; 
     return @var; 
    end 
    // 
delimiter ; 

現在你可以調用該函數與設置爲1,將功能的計數器變量回到0重置參數視圖的查詢,並以0比增加計數器。

 
CREATE OR REPLACE VIEW country_view (country, name, price, row_num) 
AS SELECT country, name, price, func_inc_var_session(0) 
FROM country 
JOIN (SELECT func_inc_var_session(1)) r 

現在你肯定行號1,2,3,每次:該功能只用1與它下面加入的時候被調用一次作爲參數。