从两个表

时间:2017-12-29 07:46:54

标签: sql sql-server sql-server-2012

我有两个具有相同列名的表。

例如:

NEEDTOSYNCREQUESTS

Column Name         Value
----------------------------
ID                  1
LoadId              L1 
ShipmentId          123 
OrderId             NULL
PackageId           P456 
CustomerOTP         99999
ClientOTP           88888

LASTSYNCEDREQUEST 表:

Column Name         Value
-------------------------
ID                  1
LoadId              L1 
ShipmentId          NULL
OrderId             1234567
PackageId           P456 
CustomerOTP         44444
ClientOTP           686868

如果您比较上表的列值,您可以看到以下内容:

  1. CustomerOTP& ClientOTP列值不相同。
  2. NEEDTOSYNCREQUESTS中的ShipmentId列具有值,LASTSYNCEDREQUEST表中的ShipmentId列为NULL。
  3. LASTSYNCEDREQUEST表中的OrderId列具有值,NEEDTOSYNCREQUESTS表中的ShipmentId列为NULL。
  4. 所以,我需要得到以下输出。怎么做到这一点?

    输出

    Column Name         Value
    ---------------------------------
    ID                  1
    LoadId              NULL 
    ShipmentId          123 
    OrderId             NULL
    PackageId           NULL
    CustomerOTP         99999
    ClientOTP           88888
    

    条件是,我需要比较上面两个表,并且在与另一个LASTSYNCEDREQUEST表进行比较时只需要更新的列值NEEDTOSYNCREQUESTS表。注意:两列都具有相同的值或者NEEDTOSYNCREQUESTS表列没有值,那么这些列在输出中应为空。表中的PackageId是相同的(相同)。所以,我需要在输出中将PackageId设为NULL。

    请帮我在SQL查询中实现此目的。

    提前致谢!

4 个答案:

答案 0 :(得分:1)

如您所见,所有字段的CASE语句中的3个WHEN中实现了相同的规则。

SELECT A.ID,
CASE WHEN A.LOADID = B.LOADID THEN NULL
     WHEN A.LOADID IS NULL THEN NULL
     WHEN (B.LOADID IS NULL AND A.LOADID IS NOT NULL) OR (A.LOADID IS NOT NULL AND B.LOADID IS NOT NULL) THEN A.LOADID END AS LOADID,
CASE WHEN A.SHIPMENTID = B.SHIPMENTID THEN NULL
     WHEN A.SHIPMENTID IS NULL THEN NULL
     WHEN (B.SHIPMENTID IS NULL AND A.SHIPMENTID IS NOT NULL) OR (A.SHIPMENTID IS NOT NULL AND B.SHIPMENTID IS NOT NULL) THEN A.SHIPMENTID END AS SHIPMENTID,
CASE WHEN A.ORDERID = B.ORDERID THEN NULL
     WHEN A.ORDERID IS NULL THEN NULL
     WHEN (B.ORDERID IS NULL AND A.ORDERID IS NOT NULL) OR (A.ORDERID IS NOT NULL AND B.ORDERID IS NOT NULL) THEN A.ORDERID END AS ORDERID,
CASE WHEN A.PACKAGEID = B.PACKAGEID THEN NULL
     WHEN A.PACKAGEID IS NULL THEN NULL
     WHEN (B.PACKAGEID IS NULL AND A.PACKAGEID IS NOT NULL) OR (A.PACKAGEID IS NOT NULL AND B.PACKAGEID IS NOT NULL) THEN A.PACKAGEID END AS PACKAGEID,
CASE WHEN A.CUSTOMEROTP = B.CUSTOMEROTP THEN NULL
     WHEN A.CUSTOMEROTP IS NULL THEN NULL
     WHEN (B.CUSTOMEROTP IS NULL AND A.CUSTOMEROTP IS NOT NULL) OR (A.CUSTOMEROTP IS NOT NULL AND B.CUSTOMEROTP IS NOT NULL) THEN A.CUSTOMEROTP END AS CUSTOMEROTP,
CASE WHEN A.CLIENTOTP = B.CLIENTOTP THEN NULL
     WHEN A.CLIENTOTP IS NULL THEN NULL
     WHEN (B.CLIENTOTP IS NULL AND A.CLIENTOTP IS NOT NULL) OR (A.CLIENTOTP IS NOT NULL AND B.CLIENTOTP IS NOT NULL) THEN A.CLIENTOTP END AS CLIENTOTP
FROM
NEEDTOSYNCREQUESTS A
INNER JOIN
LASTSYNCEDREQUEST B
ON A.ID = B.ID;

答案 1 :(得分:1)

您可以尝试基于案例的查询,如下所示 See live demo

select
    id      = N.id,
    Loadid  = case 
                when ISNULL(N.Loadid,'')=ISNULL(L.Loadid,'') 
                then NULL
                else N.LoadId
              end,
    Shipmentid=case 
                when ISNULL(N.Shipmentid,'')=ISNULL(L.Shipmentid,'') 
                then NULL
                else N.Shipmentid
              end,
    orderid=case 
                when ISNULL(N.orderid,'')=ISNULL(L.orderid,'') 
                then NULL
                else N.orderid
              end,
    packageid=case 
                when ISNULL(N.packageid,'')=ISNULL(L.packageid,'') 
                then NULL
                else N.packageid
              end,
    customerOTP=case 
                when ISNULL(N.customerOTP,'')=ISNULL(L.customerOTP,'') 
                then NULL
                else N.customerOTP
              end,
    clientOTP=case 
                when ISNULL(N.clientOTP,'')=ISNULL(L.clientOTP,'') 
                then NULL
                else N.clientOTP
              end
from
NEEDTOSYNCREQUESTS N LEFT JOIN
LASTSYNCEDREQUEST L ON
N.id=L.id

答案 2 :(得分:0)

试试这个:

SELECT n.ID, n.LoadId, n.ShipmentId,
  n.OrderId, NULL PackageId, n.CustomerOTP,
  n.ClientOTP
FROM NEEDTOSYNCREQUESTS AS n
INNER JOIN LASTSYNCEDREQUEST AS l ON n.ID = l.ID AND n.LoadId = l.LoadId
WHERE n.CustomerOTP <> l.CustomerOTP AND
      n.ClientOTP   <> l.ClientOTP
  AND n.ShipmentId IS NOT NULL
  AND l.ShipmentId IS NULL
  AND l.OrderId IS NOT NULL
  AND l.ShipmentId IS NULL;

SQL Fiddle Demo

| ID | LoadId | ShipmentId | OrderId | PackageId | CustomerOTP | ClientOTP |
|----|--------|------------|---------|-----------|-------------|-----------|
|  1 |     L1 |        123 |  (null) |    (null) |       99999 |     88888 |

请注意,我不明白为什么PackageId应该为空,因为根据您的标准,它不应该是。无论如何,我选择它作为固定的NULL值,这样无论实际值是多少,您都将获得NULL值。

答案 3 :(得分:0)

在创建数据提取或集成时,我经常需要解决这种情况。

所以我的答案将接近于此:

您可以使用 MERGE 功能并添加一些开关案例,如果您想为某些列自定义

MERGE LASTSYNCEDREQUEST TGT
USING (
 SELECT 
  ID,
  LoadId,
  ShipmentId,
  OrderId,
  PackageId,
  CustomerOTP,
  ClientOTP

FROM NEEDTOSYNCREQUESTS
) AS SRC
ON (
        SRC.ID = TGT.ID)

WHEN MATCHED
THEN
    UPDATE
    SET     
     TGT.ID = SRC.ID
    ,TGT.LoadID = NULL
    ,TGT.ShipmentID = SRC.ShipmentID
    ,TGT.OrderID = NULL
    ,TGT.PackageID = NULL
    ,TGT.CustomerOTP = SRC.CustomerOTP
    ,TGT.ClientOTP = SRC.ClientOTP


WHEN NOT MATCHED
THEN
    INSERT (

        ID,
        LoadId,
        ShipmentId,
        OrderId,
        PackageId,
        CustomerOTP,
        ClientOTP

        )
    VALUES (
         SRC.ID,
         NULL,
         SRC.ShipmentId,
         NULL,
         NULL,
         SRC.CustomerOTP,
         SRC.ClientOTP

        );

SELECT * FROM LASTSYNCEDREQUEST

你可以尝试我上面写的代码。