我有一个表,其中有一些行由日期填充,一些行具有日期但其余字段为空。寻找最有效的sql脚本来填补制造和销售价格的缺失值,我不希望更改其他空值(注意价格变化)。我想要跟随包含空值的行的相同品牌和价格。
表格的示例:
Sale_Dates | Make | Sale_Price | Year | Color
2015-01-01 | Ford | 20000.00 |2012 | Blue
2015-01-02 | NULL | NULL |NULL | NULL
2015-01-03 | NULL | NULL |NULL | NULL
2015-01-04 | Ford | 30000.00 |NULL | NULL
2015-01-05 | NULL | NULL |NULL | NULL
预期产出的例子:
Sale_Dates | Make | Sale_Price | Year | Color
2015-01-01 | Ford | 20000.00 |2012 | Blue
2015-01-02 | Ford | 20000.00 |NULL | NULL
2015-01-03 | Ford | 20000.00 |NULL | NULL
2015-01-04 | Ford | 30000.00 |NULL | NULL
2015-01-05 | Ford | 30000.00 |NULL | NULL
答案 0 :(得分:1)
由于您在评论中提及row_number
,我假设您有window functions。 (除了MySQL之外,每个现代的RDBMS都有它们。)然后有一个简单的解决方案:
SELECT sale_date
, max(make) OVER (PARTITION BY grp) AS make
, max(sale_price) OVER (PARTITION BY grp) AS sale_price
, year, color
FROM (
SELECT *, count(make) OVER (ORDER BY sale_date) AS grp
FROM tbl
ORDER BY sale_date
) sub;
假设 make
和sale_price
或NULL或 都是非空的。
更多解释:
答案 1 :(得分:0)
尽管CURSOR
有性能缺陷,但此时您可以更好地使用CURSOR
,否则您需要检查每条记录的每个NOT NULL
值。使用此功能时,您可以将最后NOT NULL
值保留在变量中。
注意:我发布此答案,希望您的数据库为SQL SERVER
。
样本表
CREATE TABLE #TEMP(Sale_Dates DATE,MAKE VARCHAR(30),Sale_Price NUMERIC(18,2),[YEAR] INT,[COLOR] VARCHAR(20))
INSERT INTO #TEMP
SELECT '2015-01-01' , 'Ford' , 20000.00 ,2012 , 'Blue'
UNION ALL
SELECT '2015-01-02' , NULL , NULL ,NULL , NULL
UNION ALL
SELECT '2015-01-03' , NULL , NULL ,NULL , NULL
UNION ALL
SELECT '2015-01-04' , 'Maruti' , 30000.00 ,NULL , NULL
UNION ALL
SELECT '2015-01-05' , NULL , NULL ,NULL , NULL
<强> QUERY 强>
DECLARE @Sale_Dates DATE
DECLARE @MAKE VARCHAR(30)
DECLARE @Sale_Price NUMERIC(20,2)=0
DECLARE @Previous_MAKE VARCHAR(30)
DECLARE @Previous_Sale_Price NUMERIC(20,2)=0
-- Here you declare which all columns you need to loop in Cursor
DECLARE CUR CURSOR FOR
SELECT Sale_Dates,MAKE,Sale_Price
FROM #TEMP
ORDER BY Sale_Dates;
OPEN CUR
-- Loop starts from here and selects each Seq and Amount of each record in each loop
FETCH NEXT FROM CUR INTO @Sale_Dates,@MAKE,@Sale_Price
WHILE @@FETCH_STATUS = 0
BEGIN
-- Updates with previous NOT NULL value
IF(@MAKE IS NULL)
BEGIN
UPDATE #TEMP SET MAKE = @Previous_MAKE
WHERE Sale_Dates = @Sale_Dates
END
-- Updates with previous NOT NULL value
IF(@Sale_Price IS NULL)
BEGIN
UPDATE #TEMP SET Sale_Price = @Previous_Sale_Price
WHERE Sale_Dates = @Sale_Dates
END
-- Store previous NOT NULL value
IF(@MAKE IS NOT NULL)
BEGIN
SET @Previous_MAKE = @MAKE
END
-- Store previous NOT NULL value
IF(@Sale_Price IS NOT NULL)
BEGIN
SET @Previous_Sale_Price = @Sale_Price
END
-- Fetches next record and increments the loop
FETCH NEXT FROM CUR INTO @Sale_Dates,@MAKE,@Sale_Price
END
CLOSE CUR;
DEALLOCATE CUR;