在查询上寻求建议

时间:2015-09-02 14:05:50

标签: tsql

我们可以在“已更改”列中获得“新记录”   对于au_id,它不存在于一个表中并存在于另一个表中

CREATE TABLE authors
(
au_id VARCHAR (100),
au_lname VARCHAR (100),
au_fname  VARCHAR (100),
phone VARCHAR (100),
address VARCHAR (100),
city VARCHAR (100),
state VARCHAR (100),
zip VARCHAR (100),
[contract] VARCHAR (100)
)

INSERT authors

SELECT '1', 'address', 'KALIA','29' ,'Second Avenue' ,     '9',' Second', 'Avenue','LALQUILA' UNION ALL
SELECT '2', 'address',  'WALIA','279' ,'Hague Way',        '79', 'Hague', 'Way','QUTUBMINAR' UNION ALL
SELECT '3', 'address',  'TOLIA','269', 'East Hague Street','69', 'East', 'Hague','Street'

SELECT * FROM authors
CREATE TABLE authorsCopy
(
au_id VARCHAR (100),
au_lname VARCHAR (100),
 au_Fname VARCHAR (100),
phone VARCHAR (100),
address VARCHAR (100),
city VARCHAR (100),
state VARCHAR (100),
zip VARCHAR (100),
[contract] VARCHAR (100)
)

INSERT authorsCopy

SELECT '1', 'address', 'KALIA','29' ,'Second CHAIBASA' ,     '9',' Second', 'Avenue','LALQUILA' UNION ALL
SELECT '2', 'address',  'WALIA','279' ,'Hague Way',        '79', 'Hague', 'Way','QUTUBMINAR' UNION ALL
SELECT '3', 'address', 'TOLIA', '269', 'East Hague Street','69', 'East', 'Hague','Street' UNION ALL
SELECT '4', 'address', 'MIR', '279' ,'TATANAGAR',        '79', 'Hague', 'Way','QUTUBMINAR' UNION ALL
SELECT '5', 'address', 'WANGDU', '269', 'GHATSILA','69', 'East', 'Hague','Street' 

SELECT * FROM authorsCopy


DECLARE  @temp TABLE(au_id VARCHAR(11) PRIMARY KEY) /*this holds the primary keys of rows that have changed */
INSERT INTO @Temp(au_ID) --determine which rows have changed
  SELECT au_ID
  FROM --use the EXCEPT technique qhich is the quickest in our tests
  (
  SELECT au_id, au_lname, au_fname, phone, [address], city, state, zip, [contract]
    FROM authors
        EXCEPT
  SELECT au_id, au_lname, au_fname, phone, address, city, state, zip, contract
    FROM authorsCopy
  )f--now we just SELECT those columns that have changed
SELECT lefthand.au_id,lefthand.name,lefthand.value AS original,Righthand.value AS changed
  FROM (--now we just lay out the two tables as key value pairs, using the string versions of the data
  SELECT authors.au_id, 'au_lname' AS 'name',au_lname AS 'value'
    FROM authors LEFT OUTER JOIN @Temp altered ON altered.au_id=authors.au_id
    UNION
  SELECT authors.au_id, 'au_fname' AS 'name',au_fname AS 'value'
    FROM authors LEFT OUTER JOIN  @Temp altered ON altered.au_id=authors.au_id
    UNION
  SELECT authors.au_id, 'phone',phone
    FROM authors LEFT OUTER JOIN  @Temp altered ON altered.au_id=authors.au_id
    UNION
  SELECT authors.au_id, 'address',address
    FROM authors LEFT OUTER JOIN  @Temp altered ON altered.au_id=authors.au_id
    UNION
  SELECT authors.au_id, 'City' AS 'name',City AS 'value'
    FROM authors LEFT OUTER JOIN  @Temp altered ON altered.au_id=authors.au_id
    UNION
  SELECT authors.au_id, 'State',state
    FROM authors LEFT OUTER JOIN  @Temp altered ON altered.au_id=authors.au_id
    UNION
  SELECT authors.au_id, 'zip',zip
    FROM authors LEFT OUTER JOIN  @Temp altered ON altered.au_id=authors.au_id
    UNION
  SELECT authors.au_id, 'contract',CONVERT(CHAR(1),contract)
    FROM authors LEFT OUTER JOIN  @Temp altered ON altered.au_id=authors.au_id) LeftHand
     LEFT OUTER JOIN (
  SELECT authorsCopy.au_id, 'au_lname' AS 'name',au_lname AS 'value'
    FROM authorsCopy LEFT OUTER JOIN  @Temp altered ON altered.au_id=authorsCopy.au_id
    UNION
  SELECT authorsCopy.au_id, 'au_fname',au_fname
    FROM authorsCopy LEFT OUTER JOIN  @Temp altered ON altered.au_id=authorsCopy.au_id
    UNION
  SELECT authorsCopy.au_id, 'phone',phone
    FROM authorsCopy LEFT OUTER JOIN  @Temp altered ON altered.au_id=authorsCopy.au_id
    UNION
  SELECT authorsCopy.au_id, 'address',address
    FROM authorsCopy LEFT OUTER JOIN  @Temp altered ON altered.au_id=authorsCopy.au_id
    UNION
  SELECT authorsCopy.au_id, 'City' AS 'name',City AS 'value'
    FROM authorsCopy LEFT OUTER JOIN  @Temp altered ON altered.au_id=authorsCopy.au_id
    UNION
  SELECT authorsCopy.au_id, 'State',state
    FROM authorsCopy LEFT OUTER JOIN  @Temp altered ON altered.au_id=authorsCopy.au_id
    UNION
  SELECT authorsCopy.au_id, 'zip',zip
    FROM authorsCopy LEFT OUTER JOIN  @Temp altered ON altered.au_id=authorsCopy.au_id
    UNION
  SELECT authorsCopy.au_id, 'contract',CONVERT(CHAR(1),contract)
    FROM authorsCopy LEFT OUTER JOIN  @Temp altered ON altered.au_id=authorsCopy.au_id) rightHand
      ON lefthand.au_ID=righthand.au_ID
    AND lefthand.name=righthand.name
  WHERE lefthand.value<>righthand.value

1 个答案:

答案 0 :(得分:1)

sqldemon,我不会假装我的解决方案是雄辩的或花哨的,因为肯定会有其他方法来实现相同的结果。也就是说,当您在声明性SQL中编写代码并且不使用函数或存储过程时,我会假设您正在寻找简单直接的东西。下面是将返回位值的查询,允许您识别来自Authors表的哪些记录是新的以及哪些记录已经以某种方式更改并识别更改的列。您可以将最终的select语句转换为另一个CTE或将其结果加载到临时表中,并使用它返回最适合您的方法(例如,新值与旧值并排)。

With New_Records as (
Select c.au_id

From #authorsCopy c
    Left Outer Join #authors a
        on a.au_id = c.au_id

Where a.au_id is null
)

Select a.au_id
    , CAST(Case
        When n.au_id is not null
            Then 1
            Else 0
        End as bit) as new_record
    , CAST(Case
        When c.au_id is not null
            Then 1
            Else 0
        End as bit) as changed_record
    , CAST(Case
        When a.au_fname <> c.au_Fname
            Then 1
            Else 0
        End as bit) as au_fname_diff
    , CAST(Case
        When a.au_lname <> c.au_lname
            Then 1
            Else 0
        End as bit) as au_lname_diff
    , CAST(Case
        When a.address <> c.address
            Then 1
            Else 0
        End as bit) as address_diff
    , CAST(Case
        When a.city <> c.city
            Then 1
            Else 0
        End as bit) as city_diff
    , CAST(Case
        When a.state <> c.state
            Then 1
            Else 0
        End as bit) as state_diff
    , CAST(Case
        When a.phone <> c.phone
            Then 1
            Else 0
        End as bit) as phone_diff
    , CAST(Case
        When a.contract <> c.contract
            Then 1
            Else 0
        End as bit) as contract_diff

From #authors a
    Left Outer Join New_Records n
        on a.au_id = n.au_id
    Left Outer Join #authorsCopy c
        on a.au_id = c.au_id
            and (a.au_fname <> c.au_Fname
                or a.au_lname <> c.au_lname
                or a.address <> c.address
                or a.city <> c.city
                or a.state <> c.state
                or a.zip <> c.zip
                or a.phone <> c.phone
                or a.contract <> c.contract)