【问题标题】:SQL join table with 0 values available具有 0 个可用值的 SQL 连接表
【发布时间】:2020-06-23 10:12:16
【问题描述】:

我在寻找正确的连接以从我的表中获取预期输出时遇到了一些麻烦。我的数据集存在于你不同的表中:

客户表

+-----------+------------+------------+-------------+--------+
| Client_No | Start_Date |   End_Date | YearOfBirth |  City  |
+-----------+------------+------------+-------------+--------+
|     1     |  1-1-2018  |    null    |    1962     |    A   |
+-----------+------------+------------+-------------+--------+
|     2     |  10-4-2016 |    null    |    1987     |    B   |
+-----------+------------+------------+-------------+--------+
|     3     | 31-12-2015 |    null    |    1992     |    A   |
+-----------+------------+------------+-------------+--------+
|     4     |  1-4-2019  | 31-12-2019 |    2001     |    B   |
+-----------+------------+------------+-------------+--------+
|     5     |  1-1-2018  |    null    |    1999     |    A   |
+-----------+------------+------------+-------------+--------+

日历表

+-----------+
|   Date    |
+-----------+
| 1-1-2019  |
+-----------+
| 1-2-2019  |
+-----------+
| 1-3-2019  |
+-----------+
| 1-4-2019  |
+-----------+
| ........  |
+-----------+
| 1-12-2020 |
+-----------+

YearOfBirth 表

+--------+
|  Year  |
+--------+
|  1910  |
+--------+
|  1911  |
+--------+
|  ....  |
+--------+
|  2020  |
+--------+

我想要一张表格,其中包含按 YearOfBirth 计算的每个城市的人口数量。但我希望它在我的日历中的每个日期都重新计数。如果 YearOfBirth 为 0,它还必须显示金额。到目前为止我得到的查询:

SELECT a.City, a.YearOfBirth, c.Date, 
       (SELECT COUNT(DISTINCT(b.ClientNo))
        FROM Client as b
        WHERE b.Start_Date < c.Date
        AND (b.End_Date > c.Date OR b.End_Date is null)
        AND a.City = b.City
        AND a.YearOfBirth = b.YearOfBirth) as Amount
FROM Client as a
FULL OUTER JOIN Calender as c
ON a.Start_Date <= c.Date
AND b.Start_Date >= c.Date
FULL OUTER JOIN YearOfBirth as d
ON a.YearOfBirth = d.YearOfBirth
GROUP BY a.City, a.YearOfBirth, c.Date

查询工作正常,但我错过了计数为 0 的所有年份。关于如何解决此问题的任何想法?

预期输出:

+------+----------+-------------+--------+
| City |   Date   | YearOfBirth | Amount |
+------+----------+-------------+--------+
|  A   | 1-1-2019 |    1910     |    0   |
+------+----------+-------------+--------+
|  A   | 1-1-2019 |    1911     |    0   |
+------+----------+-------------+--------+
|  A   | 1-1-2019 |    1912     |    0   |
+------+----------+-------------+--------+
|  A   | 1-1-2019 |    1962     |    1   |
+------+----------+-------------+--------+

我没有把所有记录都放进去,因为我希望每个城市每个日期都有一个记录,其中包含特定年份出生的人数,即使它是 0。

【问题讨论】:

  • 找到第一个子表达式,它是您可以显示的代码执行您期望的扩展,而代码不符合您的期望。 (基本调试。)然后将其扩展到minimal reproducible example,这在调试问题中是强制性的,并且应该在您的独立问题中显示为文本。--剪切、粘贴和可运行代码,包括作为代码输入的最小代表性示例;期望和实际输出(包括逐字错误消息);标签和版本;明确的规范和解释。然后解释你的期望和原因。然后问 1 个简洁的具体问题,说明为什么没有得到预期的结果。

标签: sql tsql join outer-join


【解决方案1】:

我会这样做。

使用笛卡尔连接获取城市、year_of_birth 和日期的所有可能组合的列表。

之后我只需要根据城市、year_of_birth 和 date 是否与开始和结束日期匹配,然后将值与 clienttable 中的条目进行比较,然后进行分组。

因此,在缺少 clientid 的情况下,它们将被视为 null,显示为 0

with data
  as (select c.city,a.year_of_birth,b.date
        from YearOfBirth a
        join calendar b
          on 1=1
        join (select distinct city
                from clienttable
             )c
          on 1=1 
      )
 select m.city 
       ,m.date
       ,m.year_of_birth
       ,count(clientid) as amount
   from data m
left join clienttable n
     on m.city=n.city
    and m.year_of_birth=n.year_of_birth
    and m.date between n.start_date and isnull(n.end_date,'3000-12-31')
group by m.city 
       ,m.date
       ,m.year_of_birth

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-16
    • 2015-12-24
    • 2014-03-06
    • 1970-01-01
    相关资源
    最近更新 更多