Вставить за исключением второго, добавив первый из существующих записей - PullRequest
4 голосов
/ 10 января 2012

Я хочу найти более эффективный способ, чем мое решение. Так вот в чем проблема: Я хочу получить массовую вставку из оператора select. (Справочная информация: я использую MSSQL 2005)

Пример выбора:

SELECT number, amount, year, modifiedDate, itm, city, c, d, e, f.... FROM X
JOIN Y ....

Так что, если результат

...
Num Amount Year ModifiedDate Itm City ... ...
1   100    2011 01-01-2011   2   Amsterdam .. ..
1   100    2011 01-02-2011   5   Den Haag .. ..
2   4560   2011 01-02-2011   6   Amsterdam .. .. 
33   456    2010 01-02-2011   12  Leiden .. ..
22   456    2010 01-02-2011   12  Leiden .. ..
....

В пункте назначения, который я хочу иметь:

...
Num Amount Year ModifiedDate Itm City ... ...
1   100    2011 01-02-2011   5   Den Haag .. ..
2   4560   2011 01-02-2011   6   Amsterdam .. .. 
33   456    2010 01-02-2011   12  Leiden .. ..
22   456    2010 01-02-2011   12  Leiden .. ..
....

Без этой записи: (1 100 2011 01-01-2011 2 Амстердам)

Я хочу вставить первое из этих двух в таблицу назначения. У меня есть другие записи, которые должны быть вставлены из выбора. Таким образом, в этом случае я хочу взять первый, где число, сумма и год имеют одинаковый порядок по модифицированной дате DESC. Это то, что я хочу сделать. Я уже принял решение с помощью курсора, но должен быть лучший способ.

Ответы [ 4 ]

3 голосов
/ 11 января 2012

Спасибо за все ответы. У меня появилась другая идея, которая намного быстрее, чем у курсора старой моды, и я думаю, что она соответствует тому, что я искал, поэтому я тоже делюсь ею здесь

--Test Data
DECLARE @sourceTable TABLE(number int,amount int, yr int, modifiedDate datetime, city nvarchar(100))
DECLARE @destTable TABLE(number int,amount int, yr int, modifiedDate datetime, city nvarchar(100))  

INSERT INTO @sourceTable (number, amount, yr, modifiedDate, city ) VALUES (1,100,2011,'01 Jan 2011', 'aaa')
INSERT INTO @sourceTable (number, amount, yr, modifiedDate, city ) VALUES (1,100,2011,'02 Jan 2011', 'bbb') 
INSERT INTO @sourceTable (number, amount, yr, modifiedDate, city ) VALUES (2,4560,2011,'02 Jan 2011', 'ccc') 
INSERT INTO @sourceTable (number, amount, yr, modifiedDate, city ) VALUES (33,456,2010,'02 Jan 2011', 'ddd') 
INSERT INTO @sourceTable (number, amount, yr, modifiedDate, city ) VALUES (22,456,2010,'02 Jan 2011', 'ddd') 

--Query
INSERT INTO @destTable
SELECT * FROM @sourceTable
WHERE CAST(number AS NVARCHAR(100)) + '_' + CAST(amount AS NVARCHAR(100)) + '_' + CAST(yr AS NVARCHAR(100)) + '_' + CONVERT(NVARCHAR(100), modifiedDate,121)
IN
(
SELECT CAST(number AS NVARCHAR(100)) + '_' + CAST(amount AS NVARCHAR(100)) + '_' + CAST(yr AS NVARCHAR(100)) + '_' + CONVERT(NVARCHAR(100), MAX(modifiedDate),121)
FROM @sourceTable  
GROUP BY number, amount, yr 
)  
--Results 
SELECT * FROM @destTable 
2 голосов
/ 10 января 2012

Это должно приблизить вас к тому, что вам нужно:

DECLARE @sourceTable TABLE(number int,amount int, yr int, modifiedDate datetime, itm int, City varchar(20))
DECLARE @destTable TABLE(number int,amount int, yr int, modifiedDate datetime, itm int, City varchar(20))

INSERT INTO @sourceTable (number, amount, yr, modifiedDate, Itm, City ) VALUES (1,100,2011,'01-01-2011',2,'Amsterdam')
INSERT INTO @sourceTable (number, amount, yr, modifiedDate, Itm, City ) VALUES (1,100,2011,'01-02-2011',5,'Den Haag')
INSERT INTO @sourceTable (number, amount, yr, modifiedDate, Itm, City ) VALUES (2,4560,2011,'01-02-2011',6,'Amsterdam')
INSERT INTO @sourceTable (number, amount, yr, modifiedDate, Itm, City ) VALUES (33,456,2010,'01-02-2011',12,'Leiden')
INSERT INTO @sourceTable (number, amount, yr, modifiedDate, Itm, City ) VALUES (22,456,2010,'01-02-2011',12,'Leiden')

;WITH CTE AS
(
    SELECT number, amount, yr, modifiedDate
    , ROW_NUMBER() OVER (PARTITION BY number, amount, yr ORDER BY modifiedDate DESC) AS itemRank 

    FROM @sourceTable 
    GROUP BY number, amount, yr, modifiedDate
)
INSERT INTO @destTable (number, amount, yr, modifiedDate, Itm, City )
SELECT st.number, st.amount, st.yr, st.modifiedDate, st.Itm, st.City 
FROM @sourceTable st
INNER JOIN cte ON st.number = cte.number
AND st.amount = cte.amount
AND st.yr = cte.yr
AND st.modifiedDate = cte.modifiedDate
WHERE itemRank = 1
ORDER BY modifiedDate DESC

SELECT * FROM @destTable
1 голос
/ 10 января 2012

Если я понимаю, что вы пытаетесь сделать правильно, я думаю, вам нужно сгруппировать по первым трем столбцам и выбрать значение MAX из столбца modifiedDate.

Дайте мне знать, если я неправильно понял.

SELECT   
         number, 
         amount,
         year,
         MAX(modifiedDate)
FROM     
         X
GROUP BY
         number, amount, year

Если вам также нужна помощь по INSERT части запроса, пожалуйста, дайте более подробную информацию о том, что вы там делаете в данный момент.

0 голосов
/ 10 января 2012

Группировка по всем вашим столбцам приведет к этому.

Пример:

--Test Data
DECLARE @sourceTable TABLE(number int,amount int, yr int, modifiedDate datetime)
DECLARE @destTable TABLE(number int,amount int, yr int, modifiedDate datetime)

INSERT INTO @sourceTable (number, amount, yr, modifiedDate ) VALUES (1,100,2011,'01 Jan 2011')
INSERT INTO @sourceTable (number, amount, yr, modifiedDate ) VALUES (1,100,2011,'01 Jan 2011')
INSERT INTO @sourceTable (number, amount, yr, modifiedDate ) VALUES (1,100,2011,'03 Jan 2011')
INSERT INTO @sourceTable (number, amount, yr, modifiedDate ) VALUES (1,100,2011,'02 Jan 2011')

--Query
INSERT INTO @destTable(number, amount, yr, modifiedDate )
SELECT number, amount, yr, modifiedDate
FROM @sourceTable 
GROUP BY number, amount, yr, modifiedDate
ORDER BY modifiedDate DESC

--Results
SELECT * FROM @destTable
...