【问题标题】:Left join statement returning unexpected null values for rows/column that have data左连接语句为具有数据的行/列返回意外的空值
【发布时间】:2016-08-17 14:58:10
【问题描述】:

我有两个要编写查询的表。有些列可以在其中一张表中找到,而有些列是经过计算的。

为清楚起见,我将在下面复制我的查询:

select field_a,
       cast(field_b as int),
       field_c,
       field_d,
       Year,
       coalesce( cast(field_e as float),0) America_spend,
       sum( cast(field_e as float), 0) as America_spend,
       coalesce( cast(field_e as float)/ sum( cast( field_e as float)) over(partition by Year) as total_spend
from table_a
left join table_b on
    table_a.flield_a = table_b.field_a1 and 
    table_a.flield_b = table_b.field_b1 and 
    table_a.Year = table_b.Year
group by field_a,
         field_b,
         Year

我有这样的表格

表a:

|field_a|field_b|field_c|field_d|Year|field_f|field_g|field_h
|data   |   1   | data  |  data |2014| data  | data  | data
|data   |   1   | data  |  data |2014| null  | data  | data
|0      |   1   | data  |  data |2014| data  | data  | data
|data   |   1   | data  |  data |2014| null  | data  | data
|0      |   1   | data  |  data |2014| data  | data  | data

表b:

|field_a1|field_b1|Year|field_c1|field_j
|null    |   1   |2014| data   | data
|data    |   1   |2015| data   | data
|null    |   0   |2014| data   | data
|data    |   1   |2015| data   | data
|null    |   0   |2014| data   | data

我遇到的问题是“总支出列”中的某些值被分配了 null 值。每年计算总支出,此字段不应为空。同样,年份列在任何一个表中都不包含空值。但是由于某种原因,当我运行查询时,我得到的结果在年份列中的某些行具有空值。这不应该发生。大部分结果符合我的预期,但也有一些不符合。

我猜这与 field_b 中的某些行为空并转换为 0 的事实有关,但为什么这很重要?

我更新了表格和查询以更准确地反映数据库的结构。

是的,查询运行,我没有命名冲突。

【问题讨论】:

  • 该查询真的执行了吗?
  • @jarlh 查询执行,我得到了我没有预料到的结果。
  • 好吧,当你有 NULL 时,连接不会返回匹配的行,因为 NULL NULL。不知道你为什么要投到花车上。您可能应该使用数字代替,因为浮点数是近似值。正如发布的那样,此查询不会执行,因为并非所有列都在 group by 或聚合中。
  • 1.您应该为您的表使用别名,因为例如您的分组包含一个不明确的列名。 2. 您期望 field_c 和 field_e 的哪个值?因为你根本没有按他们分组。
  • 我可以期待 MySQL 执行该查询,但是 SQL Server ??? (一般的 GROUP BY 规则说:“如果指定了 GROUP BY 子句,则 SELECT 列表中的每个列引用必须标识一个分组列或作为集合函数的参数。”)

标签: sql sql-server database join


【解决方案1】:

@SeanLange 的评论很可能是您预期结果的问题。那就是NULL 不等于NULL (NULL <> NULL)。 Null 是 sql 中的“unknown”值,两个未知数不相等。

但是,如果您想将它们作为相同的大小写匹配在一起,您可以消除您的 NULL。只需使用 COALESCE()ISNULL() 并在 ON 条件的两侧提供相同的默认值,并确保您的默认值不在数据集中表示,否则您将得到不希望的结果。

DECLARE @TableA AS TABLE (FieldA VARCHAR(5),FiledB INT,Yr INT)
DECLARE @TableB AS TABLE (FieldA VARCHAR(5),FiledC INT,Yr INT)

INSERT INTO @TableA (FieldA,FiledB,Yr)
VALUES (null,1,2014),('data',1,2015),(null,1,2014),('data',1,2015),(null,1,2014)
INSERT INTO @TableB (FieldA,FiledC,Yr)
VALUES (null,1,2014),('data',1,2015),(null,1,2014),('data',1,2015),(null,1,2014)

SELECT *
FROM
    @TableA a
    LEFT JOIN @TableB b
    ON COALESCE(a.FieldA,'NULLVALUE') = COALESCE(b.FieldA,'NULLVALUE')
    AND a.Yr = b.Yr

您提供给我们的特定示例数据集重复了 FieldA 到 Yr 组合,因此结果有点奇怪,但它仍然有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-20
    • 1970-01-01
    相关资源
    最近更新 更多