我已经尝试了一切我想过的事情,用另一个表中的值更新一个表,该值与第一个表中的列名有关。如果有人对我该如何做有任何想法,我将不胜感激。
我的存储过程中有一个与此类似的临时表...
ProductId Y2010 Y2011 Y2012 Y2013 Y2014 Y2015 Y2016 Y2017 Y2018
--------- ----- ----- ----- ----- ----- ----- ----- ----- -----
1 0 0 0 0 0 0 0 0 0
2 0 0 0 0 0 0 0 0 0
3 0 0 0 0 0 0 0 0 0
我要用于更新临时表的表与此类似...
ProductId FromYear ToYear
--------- -------- ------
1 2010 2012
2 2011 2014
1 2015 2016
3 2012 2017
2 2017 2018
我正在寻找的结果是...
ProductId Y2010 Y2011 Y2012 Y2013 Y2014 Y2015 Y2016 Y2017 Y2018
--------- ----- ----- ----- ----- ----- ----- ----- ----- -----
1 1 1 1 0 0 1 1 0 0
2 0 1 1 1 1 0 0 1 1
3 0 0 1 1 1 1 1 1 0
答案 0 :(得分:1)
只需使用条件聚合:
select productid,
max(case when 2010 between fromyear and toyear then 1 else 0 end) as Y2010,
max(case when 2011 between fromyear and toyear then 1 else 0 end) as Y2011,
. . . -- fill in with the rest of the years
max(case when 2018 between fromyear and toyear then 1 else 0 end) as Y2010,
from t
group by productid;
我不清楚您要更新现有表还是只生成这种格式。如果要更新,可以很容易地join
使用此版本,而update
可以使用原始表。
编辑:
要更新表格,您可以执行以下操作:
with newvalues as (
select productid,
max(case when 2010 between fromyear and toyear then 1 else 0 end) as Y2010,
max(case when 2011 between fromyear and toyear then 1 else 0 end) as Y2011,
. . . -- fill in with the rest of the years
max(case when 2018 between fromyear and toyear then 1 else 0 end) as Y2010,
from t
group by productid
)
update
set Y2010 = nv.Y2010,
Y2011 = nv.Y2011,
Y2012 = nv.Y2012,
Y2013 = nv.Y2013,
Y2014 = nv.Y2014,
Y2015 = nv.Y2015,
Y2016 = nv.Y2016,
Y2017 = nv.Y2017,
Y2018 = nv.Y2018
from existingtable et join
newvalues nv
on et.productid = nv.productid;
答案 1 :(得分:0)
我可以通过将第二张表设置为与第一张表相同的格式来实现此目的,方法是加入年份列表,然后对结果进行透视调整
ScrollPaneSkin
这将输出所需的结果,因此可能不需要进行更新,但是如果需要,则可以简单地联接回原始临时表:
CREATE TABLE #T (ProductId INT, FromYear INT, ToYear INT);
INSERT INTO #T (ProductId, FromYear, ToYear)
VALUES (1, 2010, 2012), (2, 2011, 2014), (1, 2015, 2016), (3, 2012, 2017), (2, 2017, 2018);
WITH Years AS
( SELECT Year
FROM (VALUES (2010), (2011), (2012), (2013), (2014), (2015), (2016), (2017), (2018)) t (Year)
), AllYears AS
( -- JOIN TO EXPAND THE RANGE INTO ONE ROW PER YEAR
SELECT t.ProductID, Year = CONCAT('Y', y.Year), Value = 1
FROM #T AS t
INNER JOIN Years AS y
ON y.Year >= t.FromYear
AND y.Year <= t.ToYear
)
SELECT *
FROM AllYears AS y
PIVOT
( MAX(Value)
FOR Year IN (Y2010, Y2011, Y2012, Y2013, Y2014, Y2015, Y2016, Y2017, Y2018)
) AS pvt;
话虽如此,我将在很大程度上提倡反对这种方法。每年将您的范围扩展到一行的查询结果可能比数据透视表的结果要消耗更多,即
CREATE TABLE #T2 (ProductId INT, Y2010 INT, Y2011 INT, Y2012 INT, Y2013 INT, Y2014 INT, Y2015 INT, Y2016 INT, Y2017 INT, Y2018 INT);
INSERT INTO #T2
(ProductId, Y2010, Y2011, Y2012, Y2013, Y2014, Y2015, Y2016, Y2017, Y2018)
VALUES
(1, 0, 0, 0, 0, 0, 0, 0, 0, 0),
(2, 0, 0, 0, 0, 0, 0, 0, 0, 0),
(3, 0, 0, 0, 0, 0, 0, 0, 0, 0);
WITH Years AS
( SELECT Year
FROM (VALUES (2010), (2011), (2012), (2013), (2014), (2015), (2016), (2017), (2018)) t (Year)
), AllYears AS
( -- JOIN TO EXPAND THE RANGE INTO ONE ROW PER YEAR
SELECT t.ProductID, Year = CONCAT('Y', y.Year), Value = 1
FROM #T AS t
INNER JOIN Years AS y
ON y.Year >= t.FromYear
AND y.Year <= t.ToYear
)
UPDATE tr
SET Y2010 = pvt.Y2010,
Y2011 = pvt.Y2011,
Y2012 = pvt.Y2012,
Y2013 = pvt.Y2013,
Y2014 = pvt.Y2014,
Y2015 = pvt.Y2015,
Y2016 = pvt.Y2016,
Y2017 = pvt.Y2017,
Y2018 = pvt.Y2018
FROM AllYears AS y
PIVOT
( MAX(Value)
FOR Year IN (Y2010, Y2011, Y2012, Y2013, Y2014, Y2015, Y2016, Y2017, Y2018)
) AS pvt
INNER JOIN #T2 AS t
ON t.ProductID = pvt.ProductID;
SELECT *
FROM #T2;
产生:
WITH Years AS
( SELECT Year
FROM (VALUES (2010), (2011), (2012), (2013), (2014), (2015), (2016), (2017), (2018)) t (Year)
)
SELECT t.ProductID, y.Year
FROM #T AS t
INNER JOIN Years AS y
ON y.Year >= t.FromYear
AND y.Year <= t.ToYear;
在表示层中进行数据透视很简单。
此方法的优势在于它是动态very straightforward to generate a list of years,因此您无需更改程序即可添加/删除年份。