2013-02-06 22 views
2

說我有以下幾點:如何在union之前在mysql中插入一行?

CREATE TABLE newtable AS (
SELECT @rownum:[email protected]+1 as rownum, name, age FROM (
    SELECT name, age FROM clubAmembers 
    UNION 
    SELECT name, age FROM clubBmembers 
) 
) AS atable 

我怎樣才能使這樣我可以「粘在新的一行在表的開頭」之前的SELECT聯盟使得它將與啓動:

rownum | name| age 
1 | "Jordan" | 6 <-- This is an arbitrarily inserted record with name="Jordan" age="6" that is not a part of any of the clubAmembers or clubBmembers table. 

表格的其餘部分(rownum 2及以上)將包含與clubAmembers然後clubBmembers的聯盟的實際結果。

基本上我要找: CREATE TABLE INSERT a row「Jordan」| 6 使用聯合執行選擇,以使第一個之後的行以「rownum = 2」開頭,來自clubAmembers的所有數據等。

如何最好地執行此操作?

+2

訂單隻能使用一個ORDER BY子句中可靠地建立。這是因爲大多數SQL(包括UNION)都是「基於集合」的。 – 2013-02-06 05:37:42

+0

SELECT @rownum:= @ rownum + 1建立命令,如果我只是聯合clubAmembers和clubBmembers(如編號1到... n的成員)。如果在保留rownum命令的同時保留這些表的聯合之前,我不可能插入一行,那麼完成我想要的操作的最佳選擇是什麼? – Setsuna

+0

它不會建立由* inside * union產生的元素的順序:選擇操作稍後發生。它可能按預期工作。或者它可能不會。 – 2013-02-06 05:40:34

回答

1

「在表的開始處」對於關係數據庫並不真正有意義,因爲直到使用ORDER BY子句時纔會保證返回訂單結果,此時磁盤上的訂單無論如何都會成爲一個爭論點。

在你的情況,因爲你想在你的結果子句來保證訂單(因此訂貨@rownum,你將不得不使用ORDER BY喜歡的東西:

CREATE TABLE newtable AS (
    SELECT @rownum:[email protected]+1 as rownum, name, age 
    FROM (
     SELECT 'Jordan' AS name, 6 AS age, 0 AS ord 
     UNION 
     SELECT name, age, 1 AS ord FROM clubAmembers 
     UNION 
     SELECT name, age, 1 AS ord FROM clubBmembers 
     ORDER BY ord 
    ) 
) AS atable 

注意,在任何時候,做這樣的保證那麼clubAmembers中的行將比clubBmembers中的行具有更低的rownum。如果你想保證clubAmembers具有較低rownum,同時保持UNION(相對於UNION ALL)語義,您可以使用以下命令:

CREATE TABLE newtable AS (
    SELECT @rownum:[email protected]+1 as rownum, name, age 
    FROM (
     SELECT 'Jordan' AS name, 6 AS age, 0 AS ord 
     UNION ALL 
     SELECT name, age, 1 AS ord FROM clubAmembers 
     UNION ALL 
     SELECT name, age, 2 AS ord FROM clubBmembers AS b 
     WHERE NOT EXISTS(SELECT 1 FROM clubAmembers AS a 
         WHERE a.name = b.name AND a.age = b.age) 
     ORDER BY ord 
    ) 
) AS atable 

注意如果{nameage}可以在clubXmembers表內被複制,你將需要添加DISTINCT

... 
SELECT DISTINCT name, age, 1 AS ord FROM clubAmembers 
UNION ALL 
... 

按照註釋中的要求,如果你有一個clubCmembers表,你會怎麼做:

CREATE TABLE newtable AS (
    SELECT @rownum:[email protected]+1 as rownum, name, age 
    FROM (
     SELECT 'Jordan' AS name, 6 AS age, 0 AS ord 
     UNION ALL 
     SELECT name, age, 1 AS ord FROM clubAmembers 
     UNION ALL 
     SELECT name, age, 2 AS ord FROM clubBmembers AS b 
     WHERE NOT EXISTS(SELECT 1 FROM clubAmembers AS a 
         WHERE a.name = b.name AND a.age = b.age) 
     SELECT name, age, 3 AS ord FROM clubCmembers AS c 
     WHERE NOT EXISTS(SELECT 1 FROM clubAmembers AS a 
         WHERE a.name = c.name AND a.age = c.age) 
     AND NOT EXISTS(SELECT 1 FROM clubBmembers AS b 
         WHERE b.name = c.name AND b.age = c.age) 
     ORDER BY ord 
    ) 
) AS atable 
+0

ord的用途是什麼?這是否意味着如果我爲clubBmembers上的SELECT設置了「2」,那麼我可以保證clubAmembers中的行數比clubBmembers中的行數要低一些? – Setsuna

+0

@SeiSeiei'ord'建立了一個排序,你的「Jordan」排首先出現('ord = 0')。如果你想讓clubA成員先到,你可以設置爲clubB成員的'2',但是'UNION'(而不是'UNION ALL')的含義將會丟失,我將編輯解釋。 –

+0

我沒有沒有? – jurgenreza

1

我不確定我是否正確。但你爲什麼不只是添加另一個工會是這樣的:

CREATE TABLE newtable AS (
SELECT @rownum:[email protected]+1 as rownum, name, age FROM (
    SELECT 1, "Jordan", 6 
    UNION ALL 
    SELECT name, age FROM clubAmembers 
    UNION ALL 
    SELECT name, age FROM clubBmembers 
) 
) AS atable 
+0

我打開OP想要插入提到的記錄(喬丹之一)在新表中的第一個位置,然後將其餘的從子查詢中。 – CloudyMarble

+0

我認爲我寫的查詢與您的查詢結果相同。你不覺得嗎? – jurgenreza

+0

您的權利,對不起,我沒有看到第一條記錄的行。 +1 – CloudyMarble

0

您可以創建表statmenet從插入statmenet分開:

  1. 創建表(你必須知道哪些colums是戈納是有)
  2. 插入您的第一個記錄(INSERT INTO .... Values(...)
  3. 用你的聲明,但與INSERT INTO,而不是創建表所示:INSERT INTO YourNewTable.... Values(YourSubQuery)(NR和列的塔伊必須匹配您的子查詢)
+0

請詢問示例。如果可能,想知道性能/速度與其他解決方案(即ORDER BY) – Setsuna

0

這應該做的,我相信:

CREATE TABLE newtable AS (
    SELECT (@rownum:=IFNULL(@rownum,0)+1)+1 as rownum, name, age FROM (
    SELECT name, age FROM clubAmembers 
    UNION 
    SELECT name, age FROM clubBmembers 
) AS s 
    UNION ALL 
    SELECT 1, 'Jordan', 6 
) AS atable 

演示在SQL小提琴:http://sqlfiddle.com/#!2/ab825/6

相關問題