SQL Server 删除或忽略多个字段重复的行

wbrvyc0a  于 2023-01-01  发布在  其他
关注(0)|答案(1)|浏览(147)

我的数据来自电力供应商。一些费用是固定的,一些是使用费。我生活在固定费用的问题。当电表在计费期间改变,两个固定费用行创建不同的meterID和合同号。其他所有字段都是相同的,我想得到其中之一。因为它是每月固定费用。
如果你帮我,我会很高兴,非常感谢,
https://www.designcise.com/web/tutorial/how-to-remove-all-duplicate-rows-except-one-in-sql#:~:text= How%20to%20Remove%20All%20Duplicate%20Rows%20Except%20One,Duplicates%20and%20Keep%20Row%20With%20Highest%20ID%20我创建了一个没有这两个字段的视图,并获取了唯一字段,然后创建了另一个视图并添加了这两个字段,给出了比真实的值小的值以供比较。我为第二个视图设置的值(A1000000 ' AS MeterUniqueNo,' 10000 '作为MeterContractID)原始示例K18 D 01652、646802)

delete from main_table 
Inner join view2 on view2.MeterUniqueNo < main_table.MeterUniqueNo
and view2.EnergyChargesRecord_InvoiceNumber = main_table.EnergyChargesRecord_InvoiceNumber
and view2.EnergyChargesRecord_MPANNumber = main_table.EnergyChargesRecord.MPANNumber

它不起作用,因为价值观不同。
T-SQL: Deleting all duplicate rows but keeping one
我不能用这个方法。因为我必须检查MPAN号和发票号。不仅仅是一个值...

hs1ihplo

hs1ihplo1#

由于您没有提供任何示例数据,我只能猜测数据的实际格式。我创建了一个最小的示例,说明如何使用ROW_NUMBER函数对重复项进行排序,并只选择最近的一个。同样,我只能猜测示例数据,但重复行之间的公共数据是MPAN_number列。这只是一个示例,请提供示例数据以获得更好的效果。或更具体的应用程序的答案。

--Create test table.
CREATE TABLE charges (
  meter_id int
  , contract_number int 
  , charge_amt decimal(19,2)
  , invoice_number int
  , MPAN_number nvarchar(100)
  , charge_date date
);

--Insert test data.
INSERT INTO charges (
  meter_id, contract_number, charge_amt, invoice_number, MPAN_number
  , charge_date)
VALUES 
 (123, 998, 25.54, 3216549, '123AM234ASF', '1/2/2022')
 , (456, 12399, 25.54, 3216668, '123AM234ASF', '1/15/2022')
 , (987, 887, 25.54, 3589765, 'K18D01652', '1/5/2022')
 , (654, 123488, 25.54, 3548892, 'K18D01652', '1/28/2022')
;

--For debugging, show all test data.
SELECT * FROM charges;

--Use a CTE to add a row_num column. 
--This row_num column will sequence "duplicate" charge lines by charge_date with the most recent charge as row_num = 1.
--The common data in the example data is the MPAN_number.
--This is only an example, for more specific help, you need to create
--a mimimal reproducible example just like this.
WITH prelim as (
  SELECT *, ROW_NUMBER() OVER(PARTITION BY MPAN_number ORDER BY charge_date DESC) as row_num
  FROM charges
)
SELECT *
FROM prelim
WHERE row_num = 1
;

--Here's an example of how to delete all "duplicate" charges that are not the most recent charge.
DELETE c 
FROM charges as c
  INNER JOIN (
    SELECT *, ROW_NUMBER() OVER(PARTITION BY MPAN_number ORDER BY charge_date DESC) as row_num
    FROM charges
  ) as oldDups
    ON oldDups.MPAN_number = c.MPAN_number
    AND oldDups.meter_id = c.meter_id
    AND oldDups.contract_number = c.contract_number
    AND oldDups.row_num <> 1
;

--For debugging, show the test data after deletions.
SELECT * FROM charges;

显示所有测试数据:
| 血糖仪_id|合同编号|电荷量|发票_编号|MPAN_编号|充电日期|
| - ------| - ------| - ------| - ------| - ------| - ------|
| 一百二十三|九九八|二十五点五四分|小行星3216549|小行星123| 2022年1月2日|
| 四百五十六|小行星123|二十五点五四分|小行星3216668|小行星123| 2022年1月15日|
| 九八七|八八七|二十五点五四分|小行星3589765|科18D01652| 2022年1月5日|
| 六五四|小行星123488|二十五点五四分|小行星354|科18D01652| 2022年1月28日|
使用SELECT显示最近的费用:
| 血糖仪_id|合同编号|电荷量|发票_编号|MPAN_编号|充电日期|行数|
| - ------| - ------| - ------| - ------| - ------| - ------| - ------|
| 四百五十六|小行星123|二十五点五四分|小行星3216668|小行星123| 2022年1月15日|1个|
| 六五四|小行星123488|二十五点五四分|小行星354|科18D01652| 2022年1月28日|1个|
显示DELETE操作后剩余的测试数据:
| 血糖仪_id|合同编号|电荷量|发票_编号|MPAN_编号|充电日期|
| - ------| - ------| - ------| - ------| - ------| - ------|
| 四百五十六|小行星123|二十五点五四分|小行星3216668|小行星123| 2022年1月15日|
| 六五四|小行星123488|二十五点五四分|小行星354|科18D01652| 2022年1月28日|
fiddle

相关问题