【问题标题】:Oracle give two parameters on multiple rows to a subquery (or from a query to another)Oracle 将多行上的两个参数提供给子查询(或从一个查询到另一个)
【发布时间】:2018-09-06 16:26:21
【问题描述】:

我正在尝试将两个参数从第一个查询提供给第二个查询:

SELECT t1.FAM,t2.CODE FROM (SELECT t1.FAM, t2.CODE FROM (SELECT num_family FROM family) t1, (SELECT num_code FROM code) t2)

所以我有我的两个参数(多行):

FAM1 | CODE1
FAM1 | CODE2
FAM1 | CODE3
FAM2 | CODE1
FAM2 | CODE2
FAM2 | CODE3

所以这是我的两个参数,我想将这两个参数放在第三个请求中:

SELECT count(*) FROM stats WHERE num_fam LIKE '%FAM1%' AND num_code LIKE '%FAM1%';

拥有:

FAM1 | CODE1 | 5
FAM1 | CODE2 | 2
FAM1 | CODE3 | 0
FAM2 | CODE1 | 9
FAM2 | CODE2 | 4
FAM2 | CODE3 | 1

但我不明白如何组合这两个查询并将第一个查询的两个参数提供给第二个查询:我尝试使用子查询和内部连接,但它没有成功......!

【问题讨论】:

  • 在这两个查询中,最后一行是否应该是FAM2?在第一个中,列名似乎不一致。在第二个中,两者都喜欢真的应该使用FAM1吗?你为什么要使用like呢? (样本数据可能会有所帮助...)
  • 第一个问题:是的,我认为是 FAM2,我更正了。对于喜欢这是因为在真正的请求中我正在做一个: SELECT ( CASE WHEN LIKE '%#'|| t2.FAM ||'%' THEN ( CASE WHEN LIKE '%#'|| t2.CODE ||'%' THEN 1 ELSE 0 END) ELSE 0 END)。这很无聊,因为我确切地知道如何使用 PL/SQL 进行操作:两个嵌套游标,带有 SELECT count(*) FROM stats WHERE FAM= param1 AND CODE = param2。但我不想在 PL/SQL 中这样做,因为我希望得到一个结果作为请求。
  • 所以你的stats 表有liste 值,比如'abc #FAM1 def #CODE1 ghi'?

标签: oracle join parameters subquery


【解决方案1】:

以下是我的想法......请检查这是否有效:

SELECT COUNT (*)
  FROM stats
 WHERE     (num_fam, num_code) IN
              (SELECT t1.FAM, t2.CODE
                 FROM (SELECT num_family FROM family) t1,
                      (SELECT num_code FROM code) t2)
       AND NUM_FAM LIKE '%FAM1%' --I assumed this is a required filter .
       AND NUM_CODE LIKE '%FAM1%';

【讨论】:

  • 这是一种有趣的方式来做我想做的事,但是在我的“真实”请求中,我必须做 CASE WHEN LISTE LIKE '%#'|| t1.FAM ||'%' THEN ( CASE WHEN LIKE '%#'|| t2.CODE ||'%' THEN 1 ELSE 0 END) ELSE 0 END 而不是 SELECT COUNT (*) FROM stats :所以我可以'不要在 WHERE 中加入 IN...
  • 好的...我想问题更多的是为您的“真实”问题创建一个紧密的模型。问题中没有像 CASE 之类的东西,现在它就在那里。因此,如果您可以修改您的问题以尽可能接近您的实际要求,这将有助于所有人进一步审查它 - 至少在我看来。
【解决方案2】:

你可以使用交叉连接和内部连接

  SELECT t1.num_family, t2.CODE, count(*) 
  FROM family t1
  CROSS JOIN code t2 
  INNER JOIN stats t3 ON  t1.num_family LIKE '%FAM1%' AND t2.num_code LIKE '%FAM1%'
  GROUP BY t1.num_family, t2.CODE 

【讨论】:

  • 我无法将 FAM1 或 CODE1 放入请求中,因为它是动态的并且取决于第一个请求...
  • 您的评论对我没有意义..您在查询中使用..为什么不能在答案中使用相同的值?
【解决方案3】:

听起来您正在交叉加入前两个表,例如使用示例数据与您显示的输出相匹配:

-- CTE for implied sample data
with family (num_family) as (
            select 'FAM1' from dual
  union all select 'FAM2' from dual
),
code (num_code) as (
            select 'CODE1' from dual
  union all select 'CODE2' from dual
  union all select 'CODE3' from dual
)
-- actual query (edited from what you showed to be valid)
--SELECT t1.FAM,t2.CODE FROM (SELECT t1.FAM, t2.CODE FROM (SELECT num_family FROM family) t1, (SELECT num_code FROM code) t2)
SELECT t1.FAM, t2.CODE FROM (SELECT num_family as fam FROM family) t1, (SELECT num_code as code FROM code) t2
/

FAM  CODE 
---- -----
FAM1 CODE1
FAM1 CODE2
FAM1 CODE3
FAM2 CODE1
FAM2 CODE2
FAM2 CODE3

甚至不需要那些子查询,因为它与:

select f.num_family, c.num_code from family f cross join code c

然后您想在 stats 表中获取匹配的 liste 值的计数,其中家庭和代码值都嵌入在该字符串中,前面有一个哈希:

我必须做 CASE WHEN LISTE LIKE '%#'|| t1.FAM ||'%' THEN (CASE WHEN LIKE '%#'|| t2.CODE ||'%' THEN 1 ELSE 0 END) ELSE 0 END 而不是 SELECT COUNT (*) FROM stats

您可以在连接条件中使用外连接和布尔逻辑来做些什么,而不是尝试使用 case 表达式:

-- CTE for implied sample data
with family (num_family) as (
            select 'FAM1' from dual
  union all select 'FAM2' from dual
),
code (num_code) as (
            select 'CODE1' from dual
  union all select 'CODE2' from dual
  union all select 'CODE3' from dual
),
stats (liste) as (
            select 'abc #FAM1 def #CODE1 ghi' from dual connect by level <= 5
  union all select 'jkl #CODE2#FAM1 mno' from dual connect by level <= 2
  union all select '#FAM2#CODE1' from dual connect by level <= 9
  union all select '#FAM2#CODE2' from dual connect by level <= 4
  union all select '#FAM2#CODE3' from dual
  union all select '#FAM2#CODE4' from dual -- no match
  union all select '#FAM3#CODE1' from dual -- no match
)
-- actual query
select f.num_family, c.num_code, count(s.liste) as matches
from family f
cross join code c
left join stats s on s.liste like '%#'|| f.num_family ||'%'
and s.liste like '%#'|| c.num_code ||'%'
group by f.num_family, c.num_code
order by f.num_family, c.num_code;

NUM_ NUM_C    MATCHES
---- ----- ----------
FAM1 CODE1          5
FAM1 CODE2          2
FAM1 CODE3          0
FAM2 CODE1          9
FAM2 CODE2          4
FAM2 CODE3          1

如果族或代码值具有重叠的根或意外的部分匹配,like 模式将会出现问题。例如。如果您的liste 值为#FAM10#CODE20,它仍将匹配FAM1CODE2。如果您可以定义一种模式来避免这些错误匹配(例如,后跟空格/标点符号/EOL),您可能会切换到regexp_like()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-13
    • 2014-08-31
    • 2014-01-16
    • 1970-01-01
    • 1970-01-01
    • 2019-09-04
    • 1970-01-01
    相关资源
    最近更新 更多