Прежде всего, я сомневаюсь, что результат это не точный?Похоже, есть три "Сэм" из оригинального стола.Но это не критично для вопроса.
Тогда мы подходим к самому вопросу.Исходя из вашей таблицы, лучший способ показать повторяющиеся значения - использовать предложения count(*)
и Group by
.Запрос будет выглядеть следующим образом:
SELECT OrderNo, shoppername, amountPayed, city, item, count(*) as RepeatTimes FROM dbo.sales GROUP BY OrderNo, shoppername, amountPayed, city, item HAVING COUNT(*) > 1
Причина в том, что все столбцы в вашей таблице однозначно идентифицируют каждую запись, что означает, что записи будут считаться дублирующими только тогда, когда все значения изкаждый столбец точно такой же, также вы хотите показать все поля для повторяющихся записей, поэтому group by
не пропустит ни один столбец, в противном случае да, потому что вы можете только select
столбцы, которые участвуют в предложении 'group by'.
Теперь я хотел бы привести любой пример для With...Row_Number()Over(...)
, который использует табличное выражение вместе с функцией Row_Number.
Предположим, у вас есть почти такая же таблица, но с одним дополнительным столбцом с именем Дата отгрузки , и стоимость может измениться, даже если остальные значения одинаковы.Вот оно:
OrderNo shoppername amountpayed city Item Shipping Date<br>
1 Sam 10 A Iphone 2016-01-01
1 Sam 10 A Iphone 2016-02-02
1 Sam 5 A Ipod 2016-03-03
2 John 20 B Macbook 2016-04-04
3 John 25 B Macbookair 2016-05-05
4 Jack 5 A Ipod 2016-06-06
Обратите внимание, что строка № 2 не является дубликатом, если вы по-прежнему принимаете все столбцы за единицу.Но что, если вы хотите рассматривать их как дубликаты в этом случае?Вы должны использовать With...Row_Number()Over(...)
, и запрос будет выглядеть следующим образом:
WITH TABLEEXPRESSION
AS
(SELECT *,ROW_NUMBER() OVER (PARTITION BY OrderNo, shoppername, amountPayed, city, item ORDER BY [Shipping Date] as Identifier) --if you consider the one with late shipping date as the duplicate
FROM dbo.sales)
SELECT * FROM TABLEEXPRESSION
WHERE Identifier !=1 --or use '>1'
Приведенный выше запрос даст результат вместе с датой доставки, например:
OrderNo shoppername amountpayed city Item Shipping Date Identifier
1 Sam 10 A Iphone 2016-02-02 2
Обратите внимание, что этот вариант отличается от того, который указан в 2016-01-01, и причина, по которой 2016-02-02 был отфильтрован, PARTITION BY OrderNo, shoppername, amountPayed, city, item ORDER BY [Shipping Date] as Identifier
, а Дата отгрузки НЕ является одной изстолбец, о котором нужно позаботиться о дубликатах записей, что означает, что столбец с 2016-02-02 все еще может быть идеальным результатом для вашего вопроса.
Теперь немного суммируйте его, используя count(*)
и *Предложение 1039 * вместе - это лучший выбор, когда вы хотите показать все столбцы из предложения Group by
как результат, в противном случае вы пропустите столбцы, которые не участвуют в group by
.
While For With...Row_Number()Over(...)
подходит для каждого сценария, в котором вы хотите найти повторяющиеся записи, однако, написать запрос немного сложнее и немного сложнее, чем предыдущий.
Если ваша цельявляется чтобы удалить дубликаты записей из таблицы, вы должны использовать более позднюю WITH...ROW_NUMBER()OVER(...)...DELETE FROM...WHERE
одну.
Надеюсь, это поможет!