【问题标题】:Trouble with Joining Tables and Obtaining Data in Oracle SQL在 Oracle SQL 中连接表和获取数据的问题
【发布时间】:2014-09-25 04:13:40
【问题描述】:

我正在使用 Oracle SQL Developer 运行我的查询。

我在 Oracle 数据库中有两个表。见下文。

                  table_1
------------------------------------------------------
    SKU    |  MAIN_LOCATION   |   BACKUP_LOCATION
------------------------------------------------------
    111    |     05-AA        |      09-DD
    222    |     02-BB        |      10-JJ
    333    |     07-CC        |      13-LL
    444    |     06-HH        |      19-PP


                  table_2
---------------------------------------------
    SKU    |    QUANTITY    |    LOCATION
---------------------------------------------
    111    |        5       |     05-AA
    111    |        8       |     09-DD
    222    |        2       |     02-BB
    333    |        4       |     07-CC
    444    |        1       |     06-HH
    444    |        11      |     19-PP
    555    |        16      |     21-UU



我需要什么
我需要的是一个查询,它显示table_1 上的所有 SKU(每行一个 SKU),以及它们在列中的数量,基于它们在table_2 的位置。如果备份位置没有提供数据,那么我只想显示一个空值。下面提供了我需要的示例。

                   QUERY NEEDED
---------------------------------------------------------------------------
  SKU  |  MAIN_LOC  |   MAIN_LOC_QTY  |   BACKUP_LOC   |   BACKUP_LOC_QTY
---------------------------------------------------------------------------
  111  |     05-AA  |       5         |    09-DD       |      8
  222  |     02-BB  |       2         |    10-JJ       |    (null)
  333  |     07-CC  |       4         |    07-CC       |    (null)
  444  |     06-HH  |       1         |    19-PP       |      11



我的尝试
我首先运行了一个查询,以确保我能够从 table_1 中提取我需要的所有 SKU。

SELECT   table_1.sku AS SKU,
         table_1.main_location AS MAIN_LOC

FROM     table_1


没问题。

然后我在查询中添加了table_2,甚至没有添加任何列,只是为了确保我获得与之前的查询相同数量的 SKU 行,这不起作用。见下文。

SELECT   table_1.sku AS SKU,
         table_1.main_location AS MAIN_LOC

FROM     table_1,
         table_2

WHERE    table_1.sku = table_2.sku(+)

这是我开始遇到问题的时候;如果 SKU 存在于 table_2 的两行中,那么它会在我的查询中显示为两行,如下所示:

  SKU  |  MAIN_LOC
--------------------
  111  |  09-DD
  111  |  09-DD
  222  |  02-BB
  333  |  07-CC
  444  |  06-HH
  444  |  06-HH

我需要以上内容仍然只显示每个 SKU 的一行。

假设上述查询甚至有效,我仍在尝试根据位置获取数量信息,如下所示:

SELECT   table_1.sku AS SKU,
         table_1.main_location AS MAIN_LOC,
         CASE
           WHEN table_1.main_location = table_2.location THEN table2.quantity
           ELSE NULL
         END AS MAIN_LOC_QUANTITY,
         table_1.backup_location AS BACKUP_LOC,
         CASE
           WHEN table_1.backup_location = table_2.location THEN table2.quantity
           ELSE NULL
         END AS BACKUP_LOC_QUANTITY

FROM     table_1,
         table_2

WHERE    table_1.sku = table_2.sku(+)


join/outer join (+) 是我获得所有我需要的 SKU 的唯一方法,但最终还是会得到相同 SKU 的重复行(这是我不想要的)。

我什至尝试在FROM 语句中进行子查询,以减少一些我不需要的 SKU,如下所示:


SELECT   table_1.sku AS SKU,
         table_1.main_location AS MAIN_LOC,
         CASE
           WHEN table_1.main_location = sub_table.location THEN sub_table.quantity
           ELSE NULL
         END AS MAIN_LOC_QUANTITY,
         table_1.backup_location AS BACKUP_LOC,
         CASE
           WHEN table_1.back_location = sub_table.location THEN sub_table.quantity
           ELSE NULL
         END AS BACKUP_LOC_QUANTITY

FROM     table_1,
         (
          SELECT  *

          FROM    table_2

          WHERE   location NOT LIKE '%[SOME CONDITIONS]%'
         ) sub_table

WHERE    table_1.sku = table_2.sku


这产生与前一个查询几乎相同的结果。它摆脱了一些我不需要的东西,但没有解决主要问题。

我还绝望地在 where 语句中添加了我对连接/外部连接知之甚少的信息:

WHERE    table_1.sku(+) = table_2.sku

还有:

WHERE    table_1.sku = table_2.sku(+)


但在这一点上,我想我只是在抓稻草,我用太多我不知道的东西淹没了自己。

我的问题是什么
A)我不知道如何让MAIN_LOC_QTY 列根据Table 2 数据显示数量。

B)当来自Table 1 的 SKU 存在于 Table 2 的两行上时,我的查询会为一个 SKU 生成两行,而我只需要一行存在与该 SKU 有关的所有信息。

任何帮助将不胜感激。谢谢!


我的解决方案是什么(2014 年 8 月 2 日更新)
对于遇到此问题的任何人,我的解决方案由下面的 Brian Demilia 提供。本质上,我的查询如下;

SELECT   table_1.sku,              --This is from table_1
         table_1.main_location,    --This is from table_1
         main_loc.quantity,        --This is from the 1st LEFT JOIN named main_loc
         table_1.backup_location,  --This is from table_1
         backup_loc.quantity       --This is from the 2nd LEFT JOIN named backup_loc

FROM     table_1
           /*LEFT JOIN below is to make table_2 with only the main_location from table_1*/
           LEFT JOIN table_2 main_loc
             ON  table_1.main_location = main_loc.location
             AND table_1.sku = main_loc.sku
           /*LEFT JOIN below is to make table_2 with only the backup_location from table_1*/
           LEFT JOIN table_2 backup_loc
             ON  table_1.backup_location = backup_loc.location
             AND table1.sku = backup_loc.sku


我希望以上内容对遇到此问题的其他人有所帮助。感谢所有的回复。

-安东尼

【问题讨论】:

  • 对于我需要什么我尝试什么以及我的问题是标题的奖励积分。现在评论...您使用的是相当旧的连接语法,虽然这可行,但使用 ansi-92 语法要容易得多。 FROM table_1, table_2 WHERE table_1.sku = table_2.sku(+) 相当于从 table_1.sku = table_2.sku 从表 1 右连接 talbe 2。我怀疑你想要这个的左连接版本。仍在阅读问题;)或者只是阅读贾斯汀的回答

标签: sql oracle select case outer-join


【解决方案1】:
select t1.sku,
       t1.main_location,
       ml.quantity        as main_qty,
       t1.backup_location,
       bl.quantity        as bkup_qty
  from table_1 t1
  left join table_2 ml
    on t1.sku = ml.sku
   and t1.main_location = ml.location
  left join table_2 bl
    on t1.sku = ml.sku
   and t1.backup_location = bl.location
 order by t1.sku

小提琴:http://sqlfiddle.com/#!4/ddbe9/4/0

【讨论】:

  • 这正是我所需要的。 SQL Fiddle 提供了非常丰富的信息。谢谢!
猜你喜欢
  • 1970-01-01
  • 2016-01-23
  • 1970-01-01
  • 2023-03-22
  • 2012-08-23
  • 2017-12-19
  • 1970-01-01
  • 2021-11-16
  • 1970-01-01
相关资源
最近更新 更多