【问题标题】:Nested Tables gives unexpected table in Oracle嵌套表在 Oracle 中提供了意外的表
【发布时间】:2020-07-05 21:03:47
【问题描述】:

这些天我正在使用这个 oracle 脚本。

create type virus_Statistic_t as object(
    vDate date,
    infection int,
    dead int,
    recovered int
)
/

create type virus_Statistic_tlb as table of virus_Statistic_t

create type countries_t as object(
    Province_or_State varchar2(50),
    Country_or_Region varchar2(100),
    Lat Number(10,6),
    Longt Number(10,6),
    virus virus_Statistic_tlb
)
/

create table countries of countries_t (
       primary key(Province_or_State, Country_or_Region)
) nested table virus store as virus_ntb;

INSERT INTO countries VALUES (
       countries_t('British Columbia', 'Canada', 49.2827, -123.1207, 
                 virus_Statistic_tlb(
                        virus_Statistic_t('22-JAN-20', 5, 0, 0), 
                        virus_Statistic_t('23-JAN-20', 10, 2, 5)
                 )
        )
);

INSERT INTO countries VALUES (
       countries_t('Queensland', 'Australia', -28.0167, 153.4, 
                 virus_Statistic_tlb(
                        virus_Statistic_t('22-JAN-20', 20, 0, 0), 
                        virus_Statistic_t('23-JAN-20', 10, 8, 10)
                 )
        )
);

select c.Province_or_State, c.Country_or_Region, c.Lat, c.Longt,  v.vDate, v.infection, v.dead, v.recovered 
from countries c, table(c.virus) v

我运行后它给了我这张桌子

PROVINCE_OR_STATE  COUNTRY_OR_REGION    LAT         LONGT    VDATE     INFECTION    DEAD    RECOVERED
British Columbia    Canada            49.2827   -123.1207   22-JAN-20   5            0      0
British Columbia    Canada            49.2827   -123.1207   23-JAN-20   10           2      5
Queensland          Australia        -28.0167    153.4      22-JAN-20   20           0      0
Queensland          Australia        -28.0167    153.4      23-JAN-20   10           8      10

但我预期的桌子是

PROVINCE_OR_STATE  COUNTRY_OR_REGION    LAT         LONGT    VDATE     INFECTION    DEAD    RECOVERED
British Columbia    Canada            49.2827   -123.1207   22-JAN-20   5            0      0
                                                            23-JAN-20   10           2      5
Queensland          Australia        -28.0167    153.4      22-JAN-20   20           0      0
                                                            23-JAN-20   10           8      10

我应该对我的代码应用哪些更改?

您可以在 here 中测试该脚本

【问题讨论】:

    标签: oracle oracle11g sqlplus


    【解决方案1】:

    当您使用 SQL*Plus 标记对其进行标记时,您需要的是 break

    这就是你现在拥有的:

    SQL> select c.Province_or_State, c.Country_or_Region, c.Lat, c.Longt,
      2         v.vDate, v.infection, v.dead, v.recovered
      3  from countries c, table(c.virus) v;
    
    PROVINCE_OR_STAT COUNTRY_OR_REGION           LAT      LONGT VDATE     INFECTION       DEAD  RECOVERED
    ---------------- -------------------- ---------- ---------- -------- ---------- ---------- ----------
    British Columbia Canada                  49,2827  -123,1207 22.01.20          5          0          0
    British Columbia Canada                  49,2827  -123,1207 23.01.20         10          2          5
    

    休息:

    SQL> break on province_or_state on country_or_region on lat on longt
    SQL> select c.Province_or_State, c.Country_or_Region, c.Lat, c.Longt,
      2         v.vDate, v.infection, v.dead, v.recovered
      3  from countries c, table(c.virus) v;
    
    PROVINCE_OR_STAT COUNTRY_OR_REGION           LAT      LONGT VDATE     INFECTION       DEAD  RECOVERED
    ---------------- -------------------- ---------- ---------- -------- ---------- ---------- ----------
    British Columbia Canada                  49,2827  -123,1207 22.01.20          5          0          0
                                                                23.01.20         10          2          5
    
    SQL>
    

    其他(报告)工具,例如 Oracle Reports Builder 或 Apex Classic Report,都有自己的突破功能。


    插入另一行后,查询(实际上是 break)仍然按预期工作:

    SQL> /
    
    PROVINCE_OR_STAT COUNTRY_OR_REGION           LAT      LONGT VDATE     INFECTION       DEAD  RECOVERED
    ---------------- -------------------- ---------- ---------- -------- ---------- ---------- ----------
    British Columbia Canada                  49,2827  -123,1207 22.01.20          5          0          0
                                                                23.01.20         10          2          5
    Queensland       Australia              -28,0167      153,4 22.01.20         20          0          0
                                                                23.01.20         10          8         10
    
    SQL>
    

    【讨论】:

    • 如果我想添加另一个省和国家会发生什么。它们也坏了吗?
    • 它们将自动被破坏 :) 您指定的不是 contents,而是您要破坏的 列名
    • 我有 Province_or_StateCountry_or_Region 作为复合键。从技术上讲,它不能重复相同。如果我必须进入另一个国家,我希望它不间断。
    • 尝试插入另一行(或其中几行)以查看其行为。
    • 我编辑了我的答案并添加了另一个输出。对我来说看起来不错(或者我没有看到明显的东西)。
    【解决方案2】:

    您正在将c.virus 转换为表,它包含两条交叉连接到主表的记录。因此,您将获得两条记录(1 条记录交叉连接 2 条记录 = 2 条记录)

    您可以按如下方式使用analytical function

    SELECT CASE WHEN RN = 1 THEN Province_or_State END AS Province_or_State,
           CASE WHEN RN = 1 THEN Country_or_Region END AS Country_or_Region,
           CASE WHEN RN = 1 THEN Lat END AS Lat,
           CASE WHEN RN = 1 THEN Longt END AS Longt,
           vDate, infection, dead, recovered 
      FROM
     (select c.Province_or_State, c.Country_or_Region, c.Lat, c.Longt,  v.vDate, v.infection, v.dead, v.recovered 
     ,ROW_NUMBER() OVER (PARTITION BY c.Province_or_State, c.Country_or_Region, c.Lat, c.Longt ORDER BY V.VDATE) AS RN,
     , DENSE_RANK() OVER (ORDER BY c.Province_or_State, c.Country_or_Region, c.Lat, c.Longt) AS DRN
      from countries c, table(c.virus) v)
     ORDER BY DRN, RN
    /
    

    db<>fiddle demo

    【讨论】:

    • 我认为我的问题不是很清楚我已经通过插入另一个值来更新我的问题。
    • 非常感谢您在一天中帮助我 :)
    猜你喜欢
    • 2021-11-26
    • 2016-08-07
    • 2012-05-10
    • 1970-01-01
    • 2022-09-26
    • 2020-10-26
    • 2012-01-03
    • 1970-01-01
    • 2011-08-28
    相关资源
    最近更新 更多