简体   繁体   English

仅联接选定的表

[英]Join only selected tables

I have A table, B table 10 different tables( 1 , 2 , 3 ,.. 10 ). 我有A表, B表10不同的表( 123 ,...... 10 )。 I have to select the data by joining any one/more of those 10 , A , and B tables based on the input. 我必须通过基于输入连接那10个, AB表中的任何一个/多个来选择数据。

Ex: If input is only 2,5,8,10 I have to join A , B , 2 , 5 , 8 , and 10 tables and retrieve the data. 例如:如果输入是仅2,5,8,10我不得不加入AB258 ,和10表和检索数据。 If input is only 1 and 7 th table , I have to join A , B , 1 , and 7 tables and retrieve the data. 如果输入仅是第1个表和第7个表,则我必须联接AB17表并检索数据。

---- sample----- ----样品-----

suppose A is a person table with p_id, p_name, order_id,.......
B is an order table with Order_id,.........
each 1-10 tables are shopping items like clothes, shoes, electronics,...etc

now I want to pull person details who orders only clothes and shoes with some other constraints like within these dates or age should be 20 like that then I have to join only person table, order table, clothes table, and shoe table and retrived the details about the persons who ordered atlease one of both the tables. 现在,我想提取仅订购具有其他限制的衣服和鞋子的人员详细信息,例如在这些日期或年龄之内应为20岁,那么我只需要加入人员表,订购表,服装表和鞋类表并检索详细信息关于订购至少两张桌子之一的人的信息。 person having only shoe or only colthes are not required. 不需要只有鞋或只有衣服的人。 result will be like how many clothes he orderd and how many shoes he ordered. 结果将类似于他订购了多少衣服和订购了多少鞋子。

Can anyone please give me some idea how to do it. 任何人都可以给我一些想法怎么做。 I am working on oracle db and using SQL. 我正在使用oracle db并使用SQL。

I don't think you can handle this with plain SQL. 我认为您无法使用普通SQL处理此问题。 It looks like you need to use dynamic SQL. 看来您需要使用动态SQL。 Have a stored procedure with parameters for the tables you need to join and then build your query based on how you call that procedure. 具有一个存储过程,该存储过程具有您需要连接的表的参数,然后根据调用该过程的方式来构建查询。 Run the query with execute immediate... Read more here: https://docs.oracle.com/cloud/latest/db112/LNPLS/dynamic.htm#LNPLS011 使用立即执行运行查询...在此处了解更多信息: https : //docs.oracle.com/cloud/latest/db112/LNPLS/dynamic.htm#LNPLS011

Update: Here's a sample with pseudo plsql as I don't have your actual data. 更新:这是伪plsql的示例,因为我没有您的实际数据。 This is just to give you an idea on how to proceed - I can't write you actual code with the given information and your setup: 这只是给您一个有关如何进行的想法-我无法使用给定的信息和您的设置为您编写实际的代码:

DECLARE
  table1  VARCHAR2 (100) := 'Table1';
  table2  VARCHAR2 (100) := '';
  table3  VARCHAR2 (100) := 'Table2';
  ...
  table10 VARCHAR2 (100) := 'Table10';
  query VARCHAR2 (4000) := '';
BEGIN
--create the core join between A and B
  query := query || 'select A.p_id, A.p_name, B.order_id from A, B where A.order_id = B.order_id ';
  IF (table1  != '') THEN query := query || ' and a.id = table1.id '; 
  --if statements for the rest of your tables and add the join condition for each table to the query string  
...

EXECUTE IMMEDIATE query;  --run the query... depends on what you want to do with the returned result you can use RETURN INTO or BULK COLLECT INTO...

EXCEPTION
  WHEN OTHERS
  THEN
    DBMS_OUTPUT.put_line (SQLERRM);
END;

Hope this helps... 希望这可以帮助...

This is sql-server syntax as far as variables but hopefully you can translate that to oracle variables. 就变量而言,这是sql-server语法,但希望您可以将其转换为oracle变量。 Anyway the trick is to use your input variables as conditions on a LEFT JOIN. 无论如何,诀窍是使用输入变量作为LEFT JOIN上的条件。 That way if the condition for your variable is false it just wont return rows from that table. 这样,如果变量的条件为false,它将不会从该表返回行。 If true it will return matches. 如果为true,则将返回匹配项。 If you really want it to be an INNER JOIN rather than a LEFT JOIN then just put a case statement in your WHERE condition to make it true if your variable condition is met. 如果您真的希望它是一个INNER JOIN而不是LEFT JOIN,则只需在您的WHERE条件中放置一个case语句,以在满足可变条件时使其为true。

DECLARE @IncludeT1 BIT, @IncludeT2 BIT

SELECT *
FROM
    TableA a
    INNER JOIN TableB B
    ON a.somecol = b.somecol
    LEFT JOIN Table1 t1
    ON a.somecol = t1.somecol
    AND @IncludeT1 = 1
    LEFT JOIN Table2 t2
    ON b.somecol = t2.solmcol
    AND @IncludeT1 = 1
WHERE
    (CASE WHEN (@IncludeT1 = 1 and t1.someid IS NOT NULL) OR @IncludeT1 = 0 THEN 1 ELSE 0 END) = 1
    AND (CASE WHEN (@IncludeT2 = 1 and t2.someid IS NOT NULL) OR @IncludeT2 = 0 THEN 1 ELSE 0 END) = 1

You can also do it via dynamic SQL as the other answer suggests there are more considerations if you go that route. 您还可以通过动态SQL来完成此操作,因为其他答案表明,如果您选择这种方法,则还有更多注意事项。

It appears your 10 different tables are actually just 10 different categories of Products . 看来您的10个不同表实际上只是10个不同类别的产品

Is it possible to homogenise them all into one big Products table with an additional field for ProductCategory (clothes, shoes, electronics, etc)? 是否可以将它们全部同质化为一个大的Products表,并为ProductCategory (衣服,鞋子,电子产品等)增加一个字段? Your assignment would then reduce to a simple WHERE on this ProductCategory field. 然后,您的分配将简化为此ProductCategory字段上的WHERE

An equivalent (albeit less efficient) view can be achieved without modifying your schema by UNION -ing all 10 tables together, upon which you can draw your assignment. 无需通过UNION修改架构即可实现等效(尽管效率较低) view ,将所有10个表放在一起,即可在其上绘制分配。

I realise this does not directly answer your question, but this would drastically simplify your problem and normalise your database, thereby eliminating the need for a complicated solution (which is always the preferred way to go). 我意识到这并不能直接回答您的问题,但是可以大大简化您的问题并使数据库规范化,从而消除了对复杂解决方案的需求(这始终是首选方法)。

I think you should go for pipe lined function with dynamic sql . 我认为您应该使用动态sql进行管道内联函数

eg you will create sql on the fly, execute it with execute immediate , return resuls row by row. 例如,您将即时创建sql,使用execute immediate ,逐行返回resuls。 Take a look here . 在这里看看。

Note that there is no accepted answer, however I think 请注意,没有可接受的答案,但是我认为

Vincent Malgrat's 文森特·马尔格拉特(Vincent Malgrat)

approach will do just fine. 方法就可以了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM