需要更好的方法从原始数据QA现有表。子集原始数据并加入现有表格并不是最好的方法

时间:2016-11-08 19:30:53

标签: sql sql-server tsql relational-database qa

表A:来自销售数据库的原始交易级数据。存在于数据库中。

表B:由其他人创建,作为原始数据的子集。存在于数据库中。

表QA:由我创建,作为从原始表A数据中提取的子集。数据库中不存在,仅存在于我的查询环境中。该表包括表B作为完全外部联接。

我的目标:检查表B是否在事务级别正确创建。 AKA原始数据子集中的每个事务都需要与开发人员从原始数据中提取的内容相匹配,如表B所示。

方法:将原始数据子集化到我的QA表中,并通过FULL OUTER JOIN将其连接到表B,然后让SQL返回表B中的数据与我的QA表中的数据不匹配的行。

问题1:我不喜欢这种用于仔细检查表B的一般方法,并且对如何解决这个问题持开放态度。

问题2:我的结束步骤不考虑何时一个值为NULL且一个值已填充。

SELECT *
INTO #QA
FROM (
         SELECT
            A.CustomerCode,
            A.ProductCode,
            A.InvoiceDate,
            A.InvoiceAmount,
            A.InvoiceQty,

            b.ProductID,

            d.CustomerID

        FROM TableA A

            --Join to Product master using Product Code in raw data to retrieve internal Product IDs
            LEFT JOIN ProductMaster b
                ON A.ProductCode = b.AProdCode

            --Join to Customer master to match Customer Code to internal Customer IDs.
            LEFT JOIN CustomerMaster d
                ON A.CustomerCode = d.ACustCode

    ) a

--Join to existing Table B which I'm trying to QA
FULL OUTER JOIN (SELECT * FROM TableB) b
    ON  a.CustomerID = b.CustID
    AND a.ProductID = b.ProdID 
    AND a.InvoiceDate = b.InvDate
    AND a.InvoiceAmount = b.InvQty
    AND a.InvoiceQty = b.InvQty;


--Return the rows where Table B doesn't match what I joined it to.
--This does not take into account when one column is NULL and the other has a value.

SELECT * FROM #QA
WHERE a.CustomerID <> b.CustID
    AND a.ProductID <> b.ProdID 
    AND a.InvoiceDate <> b.InvDate
    AND a.InvoiceAmount <> b.InvQty
    AND a.InvoiceQty <> b.InvQty;

请告诉我更好的方法。如果没有逐列更改列的所有NULL值,对于从Raw数据中提取的列为'NULL.A',对于从TableB为varchar提取的列为'NULL.B',对于整数从99999999和88888888提取的列,我想不出任何事情。< / p>

2 个答案:

答案 0 :(得分:2)

您可以使用EXCEPT关键字

SELECT * 
INTO #QA
FROM A

EXCEPT

SELECT * 
FROM B

如果返回任何内容,则表示它存在于A但不存在于B中,如果切换这两个值,它将为您提供B中不是A的所有值。

答案 1 :(得分:0)

我认为其中一种更简单的方法是为要比较的每对列创建一个case语句,将它们包装在isnull()中以赋予它们一个值,如果它们不同则返回1 ,然后选择所有不同的记录。

示例:

select * 
from
(
    select *,
        case when isnull(a.customerid, ReplaceValue) <> isnull(b.custid, ReplaceValue) then 1 else 0 end as CustomerCompare,
        case when isnull(a.nextcolumn, ReplaceValue) <> isnull(b.nextcolumn, ReplaceValue) then 1 else 0 end as ColumnCompare
    from #QA
) comparison
where customerCompare = 1 and 
    ... ColumnCompare = 1

此外,我不确定这是否是您的预期行为,但您可能希望将where子句中的AND替换为OR,以检测是否有任何列发生了更改,而不是所有列。