簡體   English   中英

合並所有不同的列

[英]Union all on different columns

我有一個查詢,要檢索到我的結果的兩列。 我使用此查詢兩次,並將這兩個查詢與UNION ALL放在一起,因為對於每條記錄,應該有另一條記錄,但是在兩列中,我根據這些值之一的值來預先設置值我設置的列。

我應該有一個將所有價格設置為DebitCredit ,如果ExamType為6,則應在Credit列中設置價格,如果ExamType為2,則應將價格設置為Debit

如果我單獨運行它們,則可以正常工作,但是一旦使用union all ,我將收到一條數據類型錯誤消息。 我已將這些列設置為NULLS,但所有內容都在Credit列下,而Debit列具有空值。 我怎樣才能解決這個問題?

帶有短“不可見”字符串的示例:

  Select StudentID, ExamDate, 2 AS ExamType, '232-442' AS Account,Amounts AS Debit, '' AS Credit 

    From TableA

    UNION ALL 

    Select StudentID, ExamDate, 6 AS ExamType, '832-446' AS Account, Amounts AS Credit, '' AS Debit

    From TableA
ORDER BY 1

NULL示例

  Select StudentID, ExamDate, 2 AS ExamType, '232-442' AS Account,NULL  AS Credit,Amounts AS Debit  

    From TableA

    UNION ALL 

    Select StudentID, ExamDate, 6 AS ExamType, '832-446' AS Account, NULL AS Debit, Amounts AS Credit, 

    From TableA
ORDER BY 1

最終結果-應如何:

    StudentID    ExamDate    ExamType  Account   Debit  Credit 
    1232111      8/9/2010    2         232-442   56.90
    1232111      8/9/2010    6         832-446          56.90 
    4773923      7/5/2010    2         232-442   46.91
    4773923      7/5/2010    6         832-446          46.91 

您似乎在UNION犯了一些錯誤。 閱讀Martin Gruber的“基本SQL”或至少閱讀Firebird(更為簡短的文檔): https : //www.firebirdsql.org/file/documentation/reference_manuals/fblangref25-zh-CN/html/fblangref25-dml-select.html# fblangref25-dml-select-union

您的簡化查詢在這里:

Select StudentID, 2 AS ExamType, NULL  AS Credit, Amounts AS Debit  
    From TableA
UNION ALL 
Select StudentID, 6 AS ExamType, NULL AS Debit, Amounts AS Credit, 
    From TableA 
ORDER BY 1

1)列命名和所需結果

Select ' ' AS Credit, Amounts AS Debit  
    From TableA
UNION ALL 
Select ' ' AS Debit, Amounts AS Credit, 
    From TableA

您希望它會產生交叉檢查的數據,例如

Debit  Credit 
        56.90 
        46.91 
56.90
46.91

真正的輸出就像

Debit  Credit 
        56.90
        46.91
        56.90 
        46.91 

您必須閱讀有關UNION子句的文檔!

列的名稱和數據類型union 的FIRST前導查詢有關。 所有后續查詢的確會適應(或無法適應)已在其之前設置的名稱和數據類型。 對於第一個之后的所有查詢,重要的是它們的列的順序。

由於查詢#1中的列#4已被稱為Credit -查詢#2中的列#4仍然如此,並且第二個查詢中的as Debit被丟棄。 第二個查詢和其他查詢的列僅按其順序映射到開頭查詢,而沒有別的。

2)列數據類型 -添加到名稱問題。

閱讀以上內容並解決名稱問題后,您可能會以類似以下內容(最小化的示例)結尾:

Select NULL AS Credit, Amounts AS Debit  
    From TableA
UNION ALL 
Select Amounts, NULL -- no names here, they do not matter
    From TableA

在這里,您最終將獲得數據類型不匹配錯誤。 為什么? 因為-您在上面閱讀過-類型是由LEADING查詢設置的,因此第一列的類型為NULL 當Firebird開始執行第二個查詢時,它將獲取一個非空的數字作為Amounts並且您的主要查詢會要求將數字轉換為NULL。 但這是不可能的。 因此錯誤。

您要做的是在該查詢中顯式告訴您想要的Firebird WHICH列數據類型,而不管列值如何。

例如,

Select StudentID, 2 AS ExamType, 
  CAST( NULL AS NUMERIC(10,2)) AS Credit,
  Amounts AS Debit  
    From TableA
UNION ALL 
Select StudentID, 6, Amounts, NULL
    From TableA

3)排序 -聯合會以菊花鏈方式鏈接完整的查詢,其中可能具有非常不同的數據源和過濾條件。 因此,排序很可能是在事實完成之后進行的,當獲取所有記錄時,這很可能是natural sorting ,而忽略了您在tableA上可能擁有的所有索引,因此在大表上應該很慢並且占用大量內存。

坦白說,在大型查詢上要提高效率,您最好用幾天前概述的EXECUTE BLOCKSTORED PROCEDURE替換UNION在一個firebird過程中顯示兩個互不相關的選擇查詢,且沒有相互的字段

對於小型查詢,盡管事后獲取自然排序的額外負擔很小,而且查詢的簡單性可能具有更大的權重。 做出你的選擇。

在Firebird中,必須鍵入列,這是從基礎列或文字值推斷出來的。 對於UNION ,第一個查詢將確定列數據類型及其名稱。 第二個(及后續)查詢必須具有與position相同的數據類型。

換句話說,您的查詢

Select StudentID, ExamDate, 2 AS ExamType, '232-442' AS Account,Amounts AS Debit, '' AS Credit 
From TableA
UNION ALL 
Select StudentID, ExamDate, 6 AS ExamType, '832-446' AS Account, Amounts AS Credit, '' AS Debit
From TableA

該查詢有兩個不同的問題:

  1. 第六列稱為Debit ,第七列稱為Credit 這意味着,即使在第二個查詢中切換名稱, 值也不會 ,這些值仍會出現在“ Debit列中。
  2. 第七列的數據類型將推斷為CHAR(1) (第二個示例為SQL_NULL ),而不是數字類型。

要解決此問題,您需要:

  1. 交換第二個查詢中的列
  2. NULL值顯式轉換為適當的類型(例如DECIMAL(18,2)

結果查詢將是

Select StudentID, ExamDate, 2 AS ExamType, '232-442' AS Account, Amounts AS Debit, CAST(NULL AS DECIMAL(18,2)) AS Credit 
From TableA
UNION ALL 
Select StudentID, ExamDate, 6 AS ExamType, '832-446' AS Account, NULL AS Debit, Amounts AS Credit
From TableA

我在第二個查詢中保留了AS子句,但它們僅用作文檔:Firebird本身會忽略它們,而僅使用第一個查詢中定義的標簽。

但是,我想知道您當前的方法是否正確:聽起來更像是一個問題,要求在student表和某些成本/財務表之間建立UNION ALL ,而不是使用UNION ALL 但是由於您的問題中缺少細節,因此很難確定。

我沒有在答案中說明必要的順序,請查看Arioch'The的答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM