X++ Union Query Views! Visual Studio Designer vs QueryBuildDataSource

By Deovandski Skibinski | March 26, 2026

Creating union queries in X++ requires careful setup to ensure consistent structure and reliable results. This guide explains how to build a union query or view in the Visual Studio Designer. It also covers a code-based approach using QueryBuildDataSource (QBDS) to implement the same query or view in X++.

Step-by-Step: Creating a Union Query in the Visual Studio Designer

Here's a step by step how to create a X++ union query/view in Visual Studio Designer!

Step 1) Create the Views

Create the views to normalize the datasources into a common format.

If the EDTs are not closely related, or you have build issues, Use Computed Fields to assist in the process.

Use of Computed Feilds to assist in union query

Step 2) Create a New Query Union

Create a new Query Union. Before adding the datasources, set the Query Type to Union.
How to set Query Type to Union

Step 3) Add the Datasources

Add the datasources and flip the Dynamic Fields to Yes, then No so that it auto populates for you.

Note: Using the Dynamic Fields toggle trick also works when you make changes to the union views then need to propagate the update to the union query.
Adding datasources and adjusting the Dynamic Fields

Step 4) Pull All Fields from the First Data Source

If you are creating a view from the union query, always pull all the fields from the first datasource in the list.
How to pull fields from the datasource

Step 5) Crosscheck the View

You can crosscheck the view on SSMS.
Note: Query unions will always cause the RecID being output appears as 1010

Why specifically 1010?

It’s just a kernel/AOS convention placeholder used for views/union outputs where a true RecId doesn’t exist. The important point is: it’s not intended to represent the source record’s RecId — it’s just “some value” so the result shape matches what the runtime expects.
Where '1010' will appear in the Query

Creating a Union Query Using QBDS

QBDS version! The following example illustrates a code-based approach to create the same union query.

You will need to do Step 1 from above first. This approach replaces steps 2-4.

class SSIQBDSUnionExample
{
    public static void main(Args _args)
    {
        SSIQBDSUnionExample::testOutput();
    }

    private static void testOutput()
    {
        Query                   q = new Query();
        QueryBuildDataSource    qbdsCust;
        QueryBuildDataSource    qbdsProj;
        QueryRun                qr;
        SSICustInvoiceView      row;

        q.queryType(QueryType::Union);

        qbdsCust = q.addDataSource(tableNum(SSICustInvoiceView), identifierStr(SSICustInvoiceView));
        qbdsCust.fields().dynamic(false);
        qbdsCust.firstOnly(true);
        qbdsCust.addSelectionField(fieldNum(SSICustInvoiceView, InvoiceAccount));
        qbdsCust.addSelectionField(fieldNum(SSICustInvoiceView, InvoiceAmount));
        qbdsCust.addSelectionField(fieldNum(SSICustInvoiceView, InvoiceDate));
        qbdsCust.addSelectionField(fieldNum(SSICustInvoiceView, InvoiceId));
        qbdsCust.addSelectionField(fieldNum(SSICustInvoiceView, unionAllBranchId));

        qbdsProj = q.addDataSource(tableNum(SSIProjInvoiceView), identifierStr(SSIProjInvoiceView), UnionType::Union);
        qbdsProj.fields().dynamic(false);
        qbdsProj.firstOnly(true);
        qbdsProj.addSelectionField(fieldNum(SSIProjInvoiceView, InvoiceAccount));
        qbdsProj.addSelectionField(fieldNum(SSIProjInvoiceView, InvoiceAmount));
        qbdsProj.addSelectionField(fieldNum(SSIProjInvoiceView, InvoiceDate));
        qbdsProj.addSelectionField(fieldNum(SSIProjInvoiceView, InvoiceId));
        qbdsProj.addSelectionField(fieldNum(SSIProjInvoiceView, unionAllBranchId));

        qr = new QueryRun(q);

        if (qr.next())
        {
            row = qr.get(tableNum(SSICustInvoiceView));
            info(strFmt("Union top1: Branch=%1 InvoiceId=%2 InvoiceDate=%3 InvoiceAccount=%4 InvoiceAmount=%5",
                        row.unionAllBranchId,
                        row.InvoiceId,
                        row.InvoiceDate,
                        row.InvoiceAccount,
                        row.InvoiceAmount));
        }
        else
        {
            info("Union top1: no records returned.");
        }
    }

}

What you will see once Union is completed

Deovandski Skibinski
Our Verified Expert
Deovandski Skibinski

Deovandski Skibinski is a developer with experience across multiple programming languages and recent expertise in X++ development for Dynamics 365 Finance and Supply Chain. He brings a passion for problem solving client challenges and enjoys sharing knowledge with fellow developers. His work spans retail, distribution, inventory, and finance, where he builds reliable, efficient solutions that help businesses run smarter. Deo holds a bachelor’s degree in Computer Science from North Dakota State University.

Read More from Deovandski Skibinski

Related Posts


Under the terms of this license, you are authorized to share and redistribute the content across various mediums, subject to adherence to the specified conditions: you must provide proper attribution to Stoneridge as the original creator in a manner that does not imply their endorsement of your use, the material is to be utilized solely for non-commercial purposes, and alterations, modifications, or derivative works based on the original material are strictly prohibited.

Responsibility rests with the licensee to ensure that their use of the material does not violate any other rights.

Start the Conversation

It’s our mission to help clients win. We’d love to talk to you about the right business solutions to help you achieve your goals.

Subscribe To Our Blog

Sign up to get periodic updates on the latest posts.

Thank you for subscribing!