我想知道如何使用SQL计算两年人口的差异。该表包含三列:国家,年份和人口。有关更多信息,您可以从以下链接中查看问题8:https://www.codecademy.com/practice/projects/world-populations-sql-practice
我尝试了以下代码,但是第一个代码需要手动计算,而另一个代码则无效。
SELECT population, year FROM population_years
WHERE country = 'Indonesia' AND year = 2000
OR country = 'Indonesia' AND year = 2010;
SELECT
(SELECT population, year FROM population_years
WHERE country = 'Indonesia' AND year = 2000) -
(SELECT population, year FROM population_years
WHERE country = 'Indonesia' AND year = 2010)
2010年和2000年印度尼西亚的人口分别为2.42亿和2.14亿。
那么我该怎么写查询才能返回28M?
谢谢!
答案 0 :(得分:1)
您可以将2000条记录和2010条记录一起添加:
SELECT p10.population - p00.population
FROM population_years p00
JOIN population_years p10 ON p10.country = p00.country
AND p10.year = 2010
WHERE p00.country = 'Indonesia'
AND p00.year = 2000
答案 1 :(得分:0)
如果您使用的是Transact-SQL,则可以使用LAG()函数:
SELECT X.MIN_YR_POP, X.MAX_YR_POP, X.NET_POP_VALUE
FROM (
SELECT PY.population AS [MAX_YR_POP], LAG(PY.population, 10, NULL) OVER(ORDER BY PY.year) AS [MIN_YR_POP]
, CONVERT(FLOAT, PY.population) - CONVERT(FLOAT, LAG(PY.population, 10, NULL) OVER(ORDER BY PY.year)) AS [NET_POP_VALUE]
FROM #_pop_yrs AS PY
) AS X
WHERE X.MIN_YR_POP IS NOT NULL
输出:
MAX_YR_POP MIN_YR_POP NET_POP_VALUE
242.96834 214.67661 28.29173
LAG()函数采用标量值,偏移值和默认值(如果无效或超出范围),然后返回已对齐所需值的表。对于上面的子查询,滞后时间为10,输出看起来像这样:
year MAX_YR_POP MIN_YR_POP NET_POP_VALUE
2000 214.67661 NULL NULL
2001 217.83628 NULL NULL
2002 220.97191 NULL NULL
2003 223.06967 NULL NULL
2004 226.00413 NULL NULL
2005 228.89575 NULL NULL
2006 231.82024 NULL NULL
2007 234.694 NULL NULL
2008 237.51236 NULL NULL
2009 240.27152 NULL NULL
2010 242.96834 214.67661 28.29173
您会得到很多不希望有的结果,因此我们创建了一个子查询并接受了我们想要的内容。
请注意,对于LAG(),您不能使用负偏移值;我们无法使用-10来回顾10行。相反,您必须知道表的顺序并相应地进行调整。如果我们想扭转结果,则我们的年度价值可能会下降:
OVER(ORDER BY PY.year DESC)
此更新的查询:
SELECT PY.population AS [MAX_YR_POP], LAG(PY.population, 10, NULL) OVER(ORDER BY PY.year DESC) AS [MIN_YR_POP]
, CONVERT(FLOAT, PY.population) - CONVERT(FLOAT, LAG(PY.population, 10, NULL) OVER(ORDER BY PY.year DESC)) AS [NET_POP_VALUE]
FROM #_pop_yrs AS PY
将返回此:
year MAX_YR_POP MIN_YR_POP NET_POP_VALUE
2010 242.96834 NULL NULL
2009 240.27152 NULL NULL
2008 237.51236 NULL NULL
2007 234.694 NULL NULL
2006 231.82024 NULL NULL
2005 228.89575 NULL NULL
2004 226.00413 NULL NULL
2003 223.06967 NULL NULL
2002 220.97191 NULL NULL
2001 217.83628 NULL NULL
2000 214.67661 242.96834 -28.29173
我们的2010年人口价值现在位于顶部,而2000年的人口价值位于底部。不过,我们是宇宙的主人,因此我们可以将ORDER BY应用于整个查询并更正输出:
SELECT PY.year, PY.population AS [MAX_YR_POP], LAG(PY.population, 10, NULL) OVER(ORDER BY PY.year DESC) AS [MIN_YR_POP]
, CONVERT(FLOAT, PY.population) - CONVERT(FLOAT, LAG(PY.population, 10, NULL) OVER(ORDER BY PY.year DESC)) AS [NET_POP_VALUE]
FROM #_pop_yrs AS PY
ORDER BY PY.year
并且:
year MAX_YR_POP MIN_YR_POP NET_POP_VALUE
2000 214.67661 242.96834 -28.29173
2001 217.83628 NULL NULL
2002 220.97191 NULL NULL
2003 223.06967 NULL NULL
2004 226.00413 NULL NULL
2005 228.89575 NULL NULL
2006 231.82024 NULL NULL
2007 234.694 NULL NULL
2008 237.51236 NULL NULL
2009 240.27152 NULL NULL
2010 242.96834 NULL NULL
可能不是您所提问题的最佳解决方案,但在某些时候它可能适用于生产线!请注意,还有一个LEAD()函数可以预见许多行。
编辑:如果您有雄心壮志,并且想要在不使用CURSOR的情况下获取所有值,则可以迭代整个过程。这是一个示例,该示例在跳过任何空年份的同时几乎计算了所有组合。它可能需要一些调整。
DECLARE @_results TABLE (
year1 CHAR(4),
year2 CHAR(4),
pop1 FLOAT,
pop2 FLOAT,
net_pop FLOAT
)
DECLARE @_count INT = 1
WHILE (@_count <= (SELECT COUNT(1) FROM #_pop_yrs))
BEGIN
INSERT INTO @_results
SELECT X.[year1], X.[year2], X.[pop1], X.[pop2], ROUND(X.[net_pop], 5) AS [net_pop]
FROM (
SELECT PY.year AS [year1]
, LAG(PY.year, @_count, NULL) OVER(ORDER BY PY.year) AS [year2]
, PY.population AS [pop1]
, LAG(PY.population, @_count, NULL) OVER(ORDER BY PY.year) AS [pop2]
, CONVERT(FLOAT, PY.population) - CONVERT(FLOAT, LAG(PY.population, @_count, NULL) OVER(ORDER BY PY.year)) AS [net_pop]
FROM #_pop_yrs AS PY
) AS X
WHERE X.[year1] IS NOT NULL AND X.year2 IS NOT NULL
SET @_count += 1
END
SELECT *
FROM @_results
ORDER BY year1, year2
输出:
year1 year2 pop1 pop2 net_pop
2001 2000 217.83628 214.67661 3.15967
2002 2000 220.97191 214.67661 6.2953
2002 2001 220.97191 217.83628 3.13563
2003 2000 223.06967 214.67661 8.39306
2003 2001 223.06967 217.83628 5.23339
2003 2002 223.06967 220.97191 2.09776
2004 2000 226.00413 214.67661 11.32752
2004 2001 226.00413 217.83628 8.16785
2004 2002 226.00413 220.97191 5.03222
2004 2003 226.00413 223.06967 2.93446
2005 2000 228.89575 214.67661 14.21914
2005 2001 228.89575 217.83628 11.05947
2005 2002 228.89575 220.97191 7.92384
2005 2003 228.89575 223.06967 5.82608
2005 2004 228.89575 226.00413 2.89162
2006 2000 231.82024 214.67661 17.14363
2006 2001 231.82024 217.83628 13.98396
2006 2002 231.82024 220.97191 10.84833
2006 2003 231.82024 223.06967 8.75057
2006 2004 231.82024 226.00413 5.81611
2006 2005 231.82024 228.89575 2.92449
2007 2000 234.694 214.67661 20.01739
2007 2001 234.694 217.83628 16.85772
2007 2002 234.694 220.97191 13.72209
2007 2003 234.694 223.06967 11.62433
2007 2004 234.694 226.00413 8.68987
2007 2005 234.694 228.89575 5.79825
2007 2006 234.694 231.82024 2.87376
2008 2000 237.51236 214.67661 22.83575
2008 2001 237.51236 217.83628 19.67608
2008 2002 237.51236 220.97191 16.54045
2008 2003 237.51236 223.06967 14.44269
2008 2004 237.51236 226.00413 11.50823
2008 2005 237.51236 228.89575 8.61661
2008 2006 237.51236 231.82024 5.69212
2008 2007 237.51236 234.694 2.81836
2009 2000 240.27152 214.67661 25.59491
2009 2001 240.27152 217.83628 22.43524
2009 2002 240.27152 220.97191 19.29961
2009 2003 240.27152 223.06967 17.20185
2009 2004 240.27152 226.00413 14.26739
2009 2005 240.27152 228.89575 11.37577
2009 2006 240.27152 231.82024 8.45128
2009 2007 240.27152 234.694 5.57752
2009 2008 240.27152 237.51236 2.75916
2010 2000 242.96834 214.67661 28.29173
2010 2001 242.96834 217.83628 25.13206
2010 2002 242.96834 220.97191 21.99643
2010 2003 242.96834 223.06967 19.89867
2010 2004 242.96834 226.00413 16.96421
2010 2005 242.96834 228.89575 14.07259
2010 2006 242.96834 231.82024 11.1481
2010 2007 242.96834 234.694 8.27434
2010 2008 242.96834 237.51236 5.45598
2010 2009 242.96834 240.27152 2.69682