【问题标题】:Difference between 'union' and 'union all' when SQL-code grades at LMS platfrom在 LMS 平台上 SQL 代码分级时“联合”和“联合全部”之间的区别
【发布时间】:2019-11-20 17:44:12
【问题描述】:

我在 LMS 平台上为练习评分时遇到问题。

我们有两个查询:

select
    distinct c.city_name,'city' obj_type
from
    shipping.city c
union all
select
    distinct c.state,'state' obj_type
from
    shipping.city c
union all
select
    distinct d.first_name,'driver' obj_type
from
    shipping.driver d
union all
select
    distinct t.Make,'truck' obj_type
from
    shipping.truck t
order by 1 desc

还有这个:

select
    c.city_name,'city' obj_type
from
    shipping.city c
union
select
    c.state,'state' obj_type
from
    shipping.city c
union
select
    d.first_name,'driver' obj_type
from
    shipping.driver d
union
select
    t.Make,'truck' obj_type
from
    shipping.truck t
order by 1 desc

两者都让我得到相同的结果,但第二个不在平台上评分。同时,我在 Metabase 中使用 except 检查结果,它告诉我“没有结果!” (空)

平台如何运作:

它将 2 个查询发送到基础并检查学生和参考响应之间的差异。

我认为在 Metabase 中,使用“union”和“union all”可能会出现参差不齐的数据视图,但与 except 比较一无所获。

更新:我解决了这个问题。两个查询中有不同的排序;平台也对其进行了检查,并且查询不同。

【问题讨论】:

  • 是的,我明白了。我不明白,为什么具有相同结果的两个查询之一不能在 platfrom 正确评分。
  • 检查结果使用EXCEPT ALL而不是EXCEPT
  • 哦!我不知道 nulls 和 exept all,谢谢!我会试试的。
  • 正如我在回答中所建议的那样,我认为您的问题是您在某些列中具有相同的值(例如两个具有相同名称的驱动程序..),因此结果集 ARE 不同,但您看不出有什么不同,因为您使用的是EXCEPT 而不是EXCEPT ALL
  • @MtwStark : 查询部分之间不能有重复,因为 {city,state,driver,truck} 文字总是不同的。

标签: sql postgresql metabase


【解决方案1】:

问题是 UNION 的三个 legs 总是不同的,因为 {city,state,driver,truck} 字面量的常量不同。因此,不会有重复,UNION 产生与UNION ALL 相同的结果。

例子:


        -- some data ...
CREATE TABLE one
        ( num integer not null
        , nam text
        );
INSERT INTO one ( num , nam ) values (1,'one'), (2, 'two'), (3, 'three');

        -- QUERY#1
SELECT 'from_first' AS "origin"
        , num, nam
FROM one
UNION
SELECT 'from_second' AS "origin"
        , num, nam
FROM one
ORDER BY 1,2
        ;

        -- QUERY#2
SELECT 'from_first' AS "origin"
        , num, nam
FROM one
UNION ALL
SELECT 'from_second' AS "origin"
        , num, nam
FROM one
ORDER BY 1,2
        ;

结果:


CREATE TABLE
INSERT 0 3
   origin    | num |  nam  
-------------+-----+-------
 from_first  |   1 | one
 from_first  |   2 | two
 from_first  |   3 | three
 from_second |   1 | one
 from_second |   2 | two
 from_second |   3 | three
(6 rows)

   origin    | num |  nam  
-------------+-----+-------
 from_first  |   1 | one
 from_first  |   2 | two
 from_first  |   3 | three
 from_second |   1 | one
 from_second |   2 | two
 from_second |   3 | three
(6 rows)

当一个或两个子选择本身产生重复时,情况就不同了,如下所示:


        -- some more data ...
CREATE TABLE two
        ( num integer not null
        , nam text
        );
INSERT INTO two ( num , nam ) values (1,'one'), (2, 'two'), (2, 'two');

        -- QUERY#1a
SELECT 'from_first' AS "origin"
        , num, nam
FROM two
UNION
SELECT 'from_second' AS "origin"
        , num, nam
FROM two
ORDER BY 1,2
        ;

        -- QUERY#2b
SELECT 'from_first' AS "origin"
        , num, nam
FROM two
UNION ALL
SELECT 'from_second' AS "origin"
        , num, nam
FROM two
ORDER BY 1,2
        ;

结果2:


CREATE TABLE
INSERT 0 3
   origin    | num | nam 
-------------+-----+-----
 from_first  |   1 | one
 from_first  |   2 | two
 from_second |   1 | one
 from_second |   2 | two
(4 rows)

   origin    | num | nam 
-------------+-----+-----
 from_first  |   1 | one
 from_first  |   2 | two
 from_first  |   2 | two
 from_second |   1 | one
 from_second |   2 | two
 from_second |   2 | two
(6 rows)

【讨论】:

    【解决方案2】:

    如果您在同一个表中有行具有相同的值或在city_namestatefirst_namemake 中具有NULL 的结果可能会有所不同。

    编辑:尝试使用EXCEPT ALL 而不是EXCEPT 检查您的结果,否则您将看不到所有差异。

    看看这个例子:

    DECLARE @T1 TABLE (name VARCHAR(10))
    DECLARE @T2 TABLE (surname VARCHAR(10))
    
    DECLARE @R1 TABLE (descr VARCHAR(10), typ VARCHAR(10))
    DECLARE @R2 TABLE (descr VARCHAR(10), typ VARCHAR(10))
    
    INSERT INTO @T1
    SELECT * 
    FROM( VALUES ('Abigail'), ('Luke'), ('Mat'), ('Mat'), ('Zoe')) x (d)
    
    INSERT INTO @T2
    SELECT * 
    FROM( VALUES ('Brown'), ('Doe'), ('Doe'), ('Smith'), ('Wilkinson')) x (d)
    
    insert into @r1
    select name descr, 'name' descr_type from @t1
    union 
    select surname descr, 'surname' descr_type from @t2
    
    insert into @r2
    select name descr, 'name' descr_type from @t1
    union all
    select surname descr, 'surname' descr_type from @t2
    
    select * from @r1
    select * from @r2
    

    如果您检查结果:

    select * from @r1
    except
    select * from @r2
    

    将产生“无结果!” (空)

    select * from @r1
    except all
    select * from @r2
    

    会产生这个结果:

    descr   typ
    'Doe'   'surname'
    'Mat'   'name'
    

    如果您想查看差异详细信息:

    select * 
        from 
            (select ROW_NUMBER() over (partition by descr order by descr) n, * from @r1) r1
        full join 
            (select ROW_NUMBER() over (partition by descr order by descr) n, * from @r2) r2 
        on r1.n= r2.n and r1.descr = r2.descr
    

    【讨论】:

      猜你喜欢
      • 2017-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-19
      • 2012-10-14
      • 2013-08-24
      • 1970-01-01
      相关资源
      最近更新 更多