Limiting a many to many join

Hello,
I__m wondering if there is a way to limit a many to many join by a specific
value in a column in the join table. I have a join table that has the two
foreign key fields which are the ids to the tables and another column that
I want to limit on. So the SQL would be something like below but I want
to do it through ejb3. Any idea how this can be accomplished?
Select phone.number, __ from company, company_phone, phone where
company_phone.primay = __Y__ and company.id = company_phone.company_id and
phone.id = company_phone.phone_id and company.id = __1234__;
If so does it work for the other relationships (one to many and many to
one)?
Thanks,
Craig

Kodo does have support for limiting a join based on a constant value; we
call them "constant joins". See the following documentation, and let us
know if you have any questions:
http://solarmetric.com/Software/Documentation/4.0.0EA/docs/full/html/ref_guide_mapping_notes_nonstdjoins.html

Similar Messages

  • JOIN for many-to-many linked tables?

    I have two tables, A and C, linked by a many-to-many intersection table B.
    I'd like to do a select from A with a LEFT OUTER JOIN to C for items mapped via B. A row in A may or may not have rows in C linked to it.
    I've tried to do a select using sub-selects but then I don't get the rows from A that don't have related rows in C.
    When I try to use the syntax of a LEFT OUTER JOIN I can't figure out how to link A and C via the B table.
    I would appreciate suggestions for how to approach this.
    Thanks in advance,
    George

    EXAMPLE
    SQL> L
      1  with A as (
      2  select 1 col1, 1 col2 from dual union all
      3  select 2     , 1     from dual union all
      4  select 3     , 2     from dual)
      5  ,
      6  B as (
      7  select 1 col2, 1 col3 from dual union all
      8  select 2     , 3     from dual)
      9  ,
    10  C as  (
    11  select 1 col3 from dual union all
    12  select 2      from dual union all
    13  select 3      from dual
    14  )
    15  select *
    16  from      A
    17  LEFT JOIN B ON (A.COL2=B.COL2)
    18* LEFT JOIN C ON (B.COL3=C.COL3)
    SQL> /
          COL1       COL2       COL2       COL3       COL3
             1          1          1          1          1
             2          1          1          1          1
             3          2          2          3          3

  • How many  types of joins are there?

    how many  types of joins are there?
    Edited by: Alvaro Tejada Galindo on Feb 21, 2008 4:58 PM

    Hi,
    Joins are used to fetch data fast from Database tables:
    Tables are joined with the proper key fields to fetch the data properly.
    If there are no proper key fields between tables don't use Joins;
    Important thing is that don't USE JOINS FOR CLUSTER tableslike BSEG and KONV.
    Only use for Transparenmt tables.
    You can also use joins for the database VIews to fetch the data.
    JOINS
    ... FROM tabref1 INNER JOIN tabref2 ON cond
    The data is to be selected from transparent database tables and/or views determined by tabref1 and tabref2. tabref1 and tabref2 each have the same form as in variant 1 or are themselves Join expressions. The keyword INNER does not have to be specified. The database tables or views determined by tabref1 and tabref2 must be recognized by the ABAP Dictionary.
    In a relational data structure, it is quite normal for data that belongs together to be split up across several tables to help the process of standardization (see relational databases). To regroup this information into a database query, you can link tables using the join command. This formulates conditions for the columns in the tables involved. The inner join contains all combinations of lines from the database table determined by tabref1 with lines from the table determined by tabref2, whose values together meet the logical condition (join condition) specified using ON>cond.
    Inner join between table 1 and table 2, where column D in both tables in the join condition is set the same:
    Table 1 Table 2
    A  B  C  D    D  E  F  G  H 
    a1  b1  c1  1    1  e1  f1  g1  h1 
    a2  b2  c2  1    3  e2  f2  g2  h2 
    a3  b3  c3  2    4  e3  f3  g3  h3 
    a4  b4  c4  3    -
    Inner Join
    A  B  C  D  D  E  F  G  H 
    a1  b1  c1  1  1  e1  f1  g1  h1 
    a2  b2  c2  1  1  e1  f1  g1  h1 
    a4  b4  c4  3  3  e2  f2  g2  h2 
    Example
    Output a list of all flights from Frankfurt to New York between September 10th and 20th, 2001 that are not sold out:
    DATA: DATE LIKE SFLIGHT-FLDATE,
    CARRID LIKE SFLIGHT-CARRID,
    CONNID LIKE SFLIGHT-CONNID.
    SELECT FCARRID FCONNID F~FLDATE
    INTO (CARRID, CONNID, DATE)
    FROM SFLIGHT AS F INNER JOIN SPFLI AS P
    ON FCARRID = PCARRID AND
    FCONNID = PCONNID
    WHERE P~CITYFROM = 'FRANKFURT'
    AND P~CITYTO = 'NEW YORK'
    AND F~FLDATE BETWEEN '20010910' AND '20010920'
    AND FSEATSOCC < FSEATSMAX.
    WRITE: / DATE, CARRID, CONNID.
    ENDSELECT.
    If there are columns with the same name in both tables, you must distinguish between them by prefixing the field descriptor with the table name or a table alias.
    In order to determine the result of a SELECT command where the FROM clause contains a join, the database system first creates a temporary table containing the lines that meet the ON condition. The WHERE condition is then applied to the temporary table. It does not matter in an inner join whether the condition is in the ON or WHEREclause. The following example returns the same solution as the previous one.
    Example
    Output of a list of all flights from Frankfurt to New York between September 10th and 20th, 2001 that are not sold out:
    DATA: DATE LIKE SFLIGHT-FLDATE,
    CARRID LIKE SFLIGHT-CARRID,
    CONNID LIKE SFLIGHT-CONNID.
    SELECT FCARRID FCONNID F~FLDATE
    INTO (CARRID, CONNID, DATE)
    FROM SFLIGHT AS F INNER JOIN SPFLI AS P
    ON FCARRID = PCARRID
    WHERE FCONNID = PCONNID
    AND P~CITYFROM = 'FRANKFURT'
    AND P~CITYTO = 'NEW YORK'
    AND F~FLDATE BETWEEN '20010910' AND '20010920'
    AND FSEATSOCC < FSEATSMAX.
    WRITE: / DATE, CARRID, CONNID.
    ENDSELECT.
    Since not all of the database systems supported by SAP use the standard syntax for ON conditions, the syntax has been restricted. It only allows those joins that produce the same results on all of the supported database systems:
    Only a table or view may appear to the right of the JOIN operator, not another join expression.
    Only AND is possible in the ON condition as a logical operator.
    Each comparison in the ON condition must contain a field from the right-hand table.
    If an outer join occurs in the FROM clause, all the ON conditions must contain at least one "real" JOIN condition (a condition that contains a field from tabref1 amd a field from tabref2.
    In some cases, '*' may be specified in the SELECT clause, and an internal table or work area is entered into the INTO clause (instead of a list of fields). If so, the fields are written to the target area from left to right in the order in which the tables appear in the FROM clause, according to the structure of each table work area. There can then be gaps between table work areas if you use an Alignment Request. For this reason, you should define the target work area with reference to the types of the database tables, not simply by counting the total number of fields. For an example, see below:
    Variant 3
    ... FROM tabref1 LEFT OUTER JOIN tabref2 ON cond
    Effect
    Selects the data from the transparent database tables and/or views specified in tabref1 and tabref2. tabref1 und tabref2 both have either the same form as in variant 1 or are themselves join expressions. The keyword OUTER can be omitted. The database tables or views specified in tabref1 and tabref2 must be recognized by the ABAP-Dictionary.
    In order to determine the result of a SELECT command where the FROM clause contains a left outer join, the database system creates a temporary table containing the lines that meet the ON condition. The remaining fields from the left-hand table (tabref1) are then added to this table, and their corresponding fields from the right-hand table are filled with ZERO values. The system then applies the WHERE condition to the table.
    Left outer join between table 1 and table 2 where column D in both tables set the join condition:
    Table 1 Table 2
    A  B  C  D    D  E  F  G  H 
    a1  b1  c1  1    1  e1  f1  g1  h1 
    a2  b2  c2  1    3  e2  f2  g2  h2 
    a3  b3  c3  2    4  e3  f3  g3  h3 
    a4  b4  c4  3    -
    Left Outer Join
    A  B  C  D  D  E  F  G  H 
    a1  b1  c1  1  1  e1  f1  g1  h1 
    a2  b2  c2  1  1  e1  f1  g1  h1 
    a3  b3  c3  2  NULL NULL NULL NULL NULL
    a4  b4  c4  3  3  e2  f2  g2  h2 
    Example
    Output a list of all custimers with their bookings for October 15th, 2001:
    DATA: CUSTOMER TYPE SCUSTOM,
    BOOKING TYPE SBOOK.
    SELECT SCUSTOMNAME SCUSTOMPOSTCODE SCUSTOM~CITY
    SBOOKFLDATE SBOOKCARRID SBOOKCONNID SBOOKBOOKID
    INTO (CUSTOMER-NAME, CUSTOMER-POSTCODE, CUSTOMER-CITY,
    BOOKING-FLDATE, BOOKING-CARRID, BOOKING-CONNID,
    BOOKING-BOOKID)
    FROM SCUSTOM LEFT OUTER JOIN SBOOK
    ON SCUSTOMID = SBOOKCUSTOMID AND
    SBOOK~FLDATE = '20011015'
    ORDER BY SCUSTOMNAME SBOOKFLDATE.
    WRITE: / CUSTOMER-NAME, CUSTOMER-POSTCODE, CUSTOMER-CITY,
    BOOKING-FLDATE, BOOKING-CARRID, BOOKING-CONNID,
    BOOKING-BOOKID.
    ENDSELECT.
    If there are columns with the same name in both tables, you must distinguish between them by prefixing the field descriptor with the table name or using an alias.
    Note
    For the resulting set of a SELECT command with a left outer join in the FROM clause, it is generally of crucial importance whether a logical condition is in the ON or WHERE condition. Since not all of the database systems supported by SAP themselves support the standard syntax and semantics of the left outer join, the syntax has been restricted to those cases that return the same solution in all database systems:
    Only a table or view may come after the JOIN operator, not another join statement.
    The only logical operator allowed in the ON condition is AND.
    Each comparison in the ON condition must contain a field from the right-hand table.
    Comparisons in the WHERE condition must not contain a field from the right-hand table.
    The ON condition must contain at least one "real" JOIN condition (a condition in which a field from tabref1 as well as from tabref2 occurs).
    Note
    In some cases, '*' may be specivied as the field list in the SELECT clause, and an internal table or work area is entered in the INTO clause (instead of a list of fields). If so, the fields are written to the target area from left to right in the order in which the tables appear in the llen in der FROM clause, according to the structure of each table work area. There can be gaps between the table work areas if you use an Alignment Request. For this reason, you should define the target work area with reference to the types of the database tables, as in the following example (not simply by counting the total number of fields).
    Example
    Example of a JOIN with more than two tables: Select all flights from Frankfurt to New York between September 10th and 20th, 2001 where there are available places, and display the name of the airline.
    DATA: BEGIN OF WA,
    FLIGHT TYPE SFLIGHT,
    PFLI TYPE SPFLI,
    CARR TYPE SCARR,
    END OF WA.
    SELECT * INTO WA
    FROM ( SFLIGHT AS F INNER JOIN SPFLI AS P
    ON FCARRID = PCARRID AND
    FCONNID = PCONNID )
    INNER JOIN SCARR AS C
    ON FCARRID = CCARRID
    WHERE P~CITYFROM = 'FRANKFURT'
    AND P~CITYTO = 'NEW YORK'
    AND F~FLDATE BETWEEN '20010910' AND '20010920'
    AND FSEATSOCC < FSEATSMAX.
    WRITE: / WA-CARR-CARRNAME, WA-FLIGHT-FLDATE, WA-FLIGHT-CARRID,
    WA-FLIGHT-CONNID.
    ENDSELECT.

  • Many to many join table with different column names

    Hi have a joint table with different column names as foreign keys in the joining
    tables...
    e.g. i have a many to many reltnshp btwn Table A and Table B ..and join table
    C
    both have a column called pk.
    and the join table C has columns call fk1 and fk2
    does cmd require the same column name in the join table as in the joining table?
    are there any workarounds?
    thanks

    HI,
    No, the foreign key column names in the join table do not have to match the primary
    key names in the joined tables.
    -thorick

  • How to resolve many-to-many join by 2 one-to-many joins

    Hi,
       I was asked many times how to resolve many to many relationship between two tables. I read to use 2 one -to- many relationships to resolve this. Can some expalin me when many to many relationship occurs between two tables and how to reslove them with practicle examples. Is there any article on this?
    Regards,
    Nanda Kishore

    Hi,
    Please check below link.
    http://www.forumtopics.com/busobj/viewtopic.php?p=859029&sid=20d79e3df07b0d8b41aadfbd902bb6b2
    http://blog.oaktonsoftware.com/2011/04/bridge-tables-and-many-to-many.html
    Thanks,
    Amit

  • Many to many join

    Hello,
    Please help me create the many-to-many relationship between these tables that I willl need to do a Master Detail form. The master is tblStandardSheets (PK: ID) the detail is tblSubject (PK: SUBJECTID) and the link is tblLink (PK: RECID, FK: ID, SUBJECTID).
    CREATE TABLE "tblStandardSheets"
    (     "ID" NUMBER NOT NULL ENABLE,
         "SHEET" VARCHAR2(100),
         "TITLE" VARCHAR2(255),
         CONSTRAINT "tblStandardSheets_PK" PRIMARY KEY ("ID") ENABLE
    CREATE OR REPLACE TRIGGER "BI_tblStandardSheets"
    before insert on "tblStandardSheets"
    for each row
    begin
    if :NEW."ID" is null then
    select "TBLSTANDARDSHEETS_SEQ".nextval into :NEW."ID" from dual;
    end if;
    end;
    ALTER TRIGGER "BI_tblStandardSheets" ENABLE
    CREATE TABLE "tblLink"
    (     "ID" NUMBER NOT NULL ENABLE,
         "RECID" NUMBER NOT NULL ENABLE,
         "SUBJECTID" NUMBER NOT NULL ENABLE,
         CONSTRAINT "tblLink_PK" PRIMARY KEY ("RECID") ENABLE
    ALTER TABLE "tblLink" ADD CONSTRAINT "TBLLINK_FK" FOREIGN KEY ("ID")
         REFERENCES "tblStandardSheets" ("ID") ON DELETE CASCADE ENABLE
    ALTER TABLE "tblLink" ADD CONSTRAINT "TBLLINK_FK2" FOREIGN KEY ("SUBJECTID")
         REFERENCES "tblSubject" ("SUBJECTID") ON DELETE CASCADE ENABLE
    CREATE OR REPLACE TRIGGER "BI_tblLink"
    before insert on "tblLink"
    for each row
    begin
    if :NEW."RECID" is null then
    select "TBLLINK_SEQ".nextval into :NEW."RECID" from dual;
    end if;
    end;
    ALTER TRIGGER "BI_tblLink" ENABLE
    CREATE TABLE "tblSubject"
    (     "SUBJECTID" NUMBER NOT NULL ENABLE,
         "SUBJECT" VARCHAR2(255),
         CONSTRAINT "tblSubject_PK" PRIMARY KEY ("SUBJECTID") ENABLE
    CREATE OR REPLACE TRIGGER "BI_tblSubject"
    before insert on "tblSubject"
    for each row
    begin
    if :NEW."SUBJECTID" is null then
    select "TBLSUBJECT_SEQ".nextval into :NEW."SUBJECTID" from dual;
    end if;
    end;
    ALTER TRIGGER "BI_tblSubject" ENABLE
    ALTER TABLE "tblSubject" ADD CONSTRAINT "tblSubject_FK" FOREIGN KEY ("SUBJECTID")
         REFERENCES "tblLink" ("SUBJECTID") ON DELETE CASCADE ENABLE
    ORA-02270: no matching unique or primary key for this column-list
    Edited by: user6753348 on Mar 31, 2009 1:39 PM

    Like this:
      CREATE TABLE "tblStandardSheets"
       (     "ID" NUMBER NOT NULL ENABLE,
         "SHEET" VARCHAR2(100 BYTE),
         "TITLE" VARCHAR2(255 BYTE),
          CONSTRAINT "tblStandardSheets_PK" PRIMARY KEY ("ID")
    CREATE OR REPLACE TRIGGER "BI_tblStandardSheets"
    before insert on "tblStandardSheets"
    for each row
    begin
    if :NEW."ID" is null then
    select "TBLSTANDARDSHEETS_SEQ".nextval into :NEW."ID" from dual;
    end if;
    end;
    ALTER TRIGGER "BI_tblStandardSheets" ENABLE
      CREATE TABLE "tblSubject"
       (     "SUBJECTID" NUMBER NOT NULL ENABLE,
         "SUBJECT" VARCHAR2(255 BYTE),
          CONSTRAINT "tblSubject_PK" PRIMARY KEY ("SUBJECTID")
    CREATE OR REPLACE TRIGGER "BI_tblSubject"
    before insert on "tblSubject"
    for each row
    begin
    if :NEW."SUBJECTID" is null then
    select "TBLSUBJECT_SEQ".nextval into :NEW."SUBJECTID" from dual;
    end if;
    end;
    ALTER TRIGGER "BI_tblSubject" ENABLE
      CREATE TABLE "HR"."tblLink"
       (     "ID" NUMBER NOT NULL ENABLE,
         "RECID" NUMBER NOT NULL ENABLE,
         "SUBJECTID" NUMBER NOT NULL ENABLE,
          CONSTRAINT "tblLink_PK" PRIMARY KEY ("RECID")
          CONSTRAINT "TBLLINK_FK" FOREIGN KEY ("ID")
           REFERENCES "tblStandardSheets" ("ID") ON DELETE CASCADE ENABLE,
          CONSTRAINT "TBLLINK_FK2" FOREIGN KEY ("SUBJECTID")
           REFERENCES "tblSubject" ("SUBJECTID") ON DELETE CASCADE ENABLE
    CREATE OR REPLACE TRIGGER "BI_tblLink"
    before insert on "tblLink"
    for each row
    begin
    if :NEW."RECID" is null then
    select "TBLLINK_SEQ".nextval into :NEW."RECID" from dual;
    end if;
    end;
    ALTER TRIGGER "BI_tblLink" ENABLE
    /You have to create the sequences yourself...
    HTH
    Roel

  • Insert/delete many to many join in 9.0.3

    Can anyone tell me a good way to create/delete an intersection row in a many to many relationship? I can do it programmatically in the client, but I'd rather have the middle tier view object or application module handle the code. Currently I'm creating a JClient application but later I will be putting the application in a browser. I don't want to rewrite the code every time I change my client application.
    Thanks

    I forgot to mention that I'm using the BC4J framework.
    Mike

  • Denormalize many-to-many

    I'm trying to create a denormalized view of my data that uses a typical join table to accomplish a many-to-many structure. The three tables involved are:
    CREATE TABLE  "POC_SUBNETS"
       (     "ID" NUMBER,
         "OCTET1" NUMBER,
         "OCTET2" NUMBER,
         "OCTET3" NUMBER,
         "OCTET4" NUMBER,
         "SLASH" VARCHAR2(30),
         "MASK" VARCHAR2(30),
         "DESCRIPTION" VARCHAR2(255),
         "ASSIGNED" VARCHAR2(3),
          CONSTRAINT "POC_SUBNETS_PK" PRIMARY KEY ("ID") ENABLE,
          CONSTRAINT "POC_SN_ASSGN_CON" CHECK ( "ASSIGNED" in ('YES', 'NO')) ENABLE
    CREATE TABLE  "POC_CONTACTS"
       (     "UNID" VARCHAR2(30),
         "FNAME" VARCHAR2(30),
         "LNAME" VARCHAR2(30),
         "DESK_PHONE" VARCHAR2(30),
         "CELL_PHONE" VARCHAR2(30),
         "PAGER" VARCHAR2(30),
         "OTHER_PHONE" VARCHAR2(30),
         "EMAIL" VARCHAR2(50),
         "ORG_ID" VARCHAR2(10),
          CONSTRAINT "POC_CONTACTS_PK" PRIMARY KEY ("UNID") ENABLE,
          CONSTRAINT "POC_CONTACTS_CON" UNIQUE ("FNAME", "LNAME") ENABLE
    CREATE TABLE  "POC_SUBNET_CONTACTS"
       (     "SUBNET_ID" NUMBER,
         "UNID" VARCHAR2(30),
         "CTYPE" VARCHAR2(30),
          CONSTRAINT "POC_SUBNET_CONTACTS_PK" PRIMARY KEY ("SUBNET_ID", "UNID", "CTYPE") ENABLE
       )Obviously, this structure will allow many contacts to have many subnets but each entry in poc_subnet_contacts must be a unique combination of subnet_id, unid, and ctype.
    Well, now that we've satisfied our requirement to allow this arrangement the users want to see a denormalized view of the data whereby the subnets show each of the zero to n contacts on the same row as the subnet. Something like this:
    subnet_id, unid1, unid2, unid3, unidn, etc...
    In truth, I can limit the number of contacts shown per subnet to 3, but I'm curious what the best way of accomplishing this denormalized view is. Here's something that I came up with:
    select id, octet1, octet2, octet3, octet4,
    (select unid from poc_subnet_contacts where id = subnet_id and ctype = 'LAN') LAN_UNID,
    (select unid from poc_subnet_contacts where id = subnet_id and ctype = 'SEC') SEC_UNID,
    (select unid from poc_subnet_contacts where id = subnet_id and ctype = 'NSC') NSC_UNID,
    (select unid from poc_subnet_contacts where id = subnet_id and ctype = 'FAC') FAC_UNID
    from poc_subnetsThis has the obvious limitation that the contact has to be of a specific type to appear and those may not always exist.
    There also could be multiple contacts of the same type that I would like to show, if possible. This situation has caused the dreaded ORA-01427: single-row subquery returns more than one row error.
    Would a materialized view help in this situation?
    Earl

    biswabijay,
    Thanks for the reply. What you've suggested works similarly to my original - presumably without the problem of returning multiple rows for a single row query because of the use of MAX. That's a step in the right direction. Thank you for that.
    What about the idea of being able to more dynamically add columns and the case where I might want to show multiple contacts of the same type on one row? Any ideas?
    In Excel and Access this is called a crosstab query. Is there anything similar in Oracle?
    Earl
    P.S. I apologize in advance for mentioning the 'E' and 'A' words here on the Oracle forums. And no, I don't want to use 'E' OR 'A'. Thank you.

  • Many-to-many performance issue

    I realize that many-to-many joins have been discussed before (yes, I looked through many threads), but I'm having a slight variation on the issue. Our data warehouse has been functioning for a couple of years now, but we're now experiencing a dramatic degradation in report performance. I'll tell you everything I know and what I've tried. My hope is that someone will have an idea that hasn't occurred to me yet.
    The troubling data links deal with accounts and account_types. Each transaction will have one account, but each account can have multiple account_types and each account_type is made up of multiple accounts. It ends up looking like this:
    Transaction_cube --< account_dimension >--< account_type_table
    Given the many-to-many relationship between account and account_type, this is the only architecture I could come up with that will maintain data integrity in the transaction cube.
    I know that this is the cause of the performance issues because the reports run normally when this is removed. The volume of data obviously increases over time, but the problem appeared very suddenly -- not a gradual degradation that one would expect from a volume issue. The cube is partitioned by year and we're a little below last year's growth.
    The other fact to throw in is that the account_type table did increase in size by an additional 30% when we first noticed the problem. However, the business was able to go back and remove half of the account_types (unused types) so now the table has fewer rows than it had before we noticed the problem (~15k rows in the account_type table).
    We have tried pinning the table so that it remain in memory, but that did not help. I tried creating a materialized view combining accounts and account_types with a similar lack of improvement. I've tried adding indexes, but there is still a full-table scan. All database objects are analyzed nightly after the data load is completed.
    I'm fresh out of ideas at this point. Any suggestions and/or ideas would be greatly appreciated.

    I've thought about that. What it would mean would be aprox. 20 additional columns for each of the different account_types. Unfortunately, that would also mean that all the reports that use the account_type would have to have a condition:
    WHERE acct_type1='Income Stmt." OR acct_type2='Income Stmt." OR ....
    Since the account_types are not set up in a hierarchy and there must be only one row for account, I'm not sure that this is a feasible solution.
    Thank you for the suggestion.

  • Creating data in a many-to-many-relationship

    Hello,
    we really have problems in implementing a JClient dialog based on BC4J for creating data in a many to many relationship - especially with cascade delete on both sides.
    Simplified our tables look like:
    create table A_TABLE
    A_ID VARCHAR2(5) not null,
    A_NAME VARCHAR2(30) not null,
    constraint PK_A_TABLE primary key (A_ID),
    constraint UK_A_TABLE unique (A_NAME)
    create table B_TABLE
    B_ID VARCHAR2(5) not null,
    B_NAME VARCHAR2(30) not null,
    constraint PK_B_TABLE primary key (B_ID),
    constraint UK_B_TABLE unique (B_NAME)
    create table AB_TABLE
    A_ID VARCHAR2(5) not null,
    B_ID VARCHAR2(5) not null,
    constraint PK_AB_TABLE primary key (A_ID, B_ID),
    constraint FK_AB_A foreign key (A_ID) references A_TABLE (A_ID) on delete cascade,
    constraint FK_AB_B foreign key (B_ID) references B_TABLE (B_ID) on delete cascade
    Could JDev Team please provide a BC4J/JClient sample that performs the following task:
    The dialog should use A_TABLE as master and AB_TABLE as detail. The detail displays the names associated with the IDs. Next to AB_TABLE should be a view of B_TABLE which only displays rows that are currently not in AB_TABLE. Two buttons are used for adding and removing rows in AB_TABLE. After adding or removing rows in the intersection the B_TABLE view should be updated. The whole thing should work in the middle and client tier. This means no database round trips after each add/remove, no posts for AB_TABLE and no query reexecution for B_TABLE until commit/rollback.
    This is a very common szenario: For an item group (A_TABLE) one can select and deselect items (AB_TABLE) from a list of available items (B_TABLE). Most of JDeveloper4s wizards use this. They can handle multi/single selections, selections from complex structures like trees and so on. Ok, the wizards are not based on BC4J - or? How can we do it with BC4J?
    Our main problems are:
    1. Updating the view of B_TABLE after add/remove reflecting the current selection
    2. A good strategy for displaying the names instead of the IDs (subqueries or joining the three tables)
    3. A JBO-27101 DeadEntityAccessException when removing an existing row from AB_TABLE and adding it again
    Other problems:
    4. We get a JBO-25030 InvalidOwnerException when creating a row in AB_TABLE. This is caused by the composition. We workaround this using createAndInitRow(AttributeList) on the view object (instead of create()). This is our add-Action:
    ViewObject abVO = panelBinding.getApplicationModule().findViewObject("ABView");
    ViewObject bVO = panelBinding.getApplicationModule().findViewObject("BView");
    Row bRow = bVO.getCurrentRow();
    NameValuePairs attribList = new NameValuePairs(
    new String[]{"BId"}, new Object[]{bRow.getAttribute("BId")});
    Row newRow = abVO.createAndInitRow(attribList);
    abVO.insertRow(newRow);
    5. After inserting the new row the NavigationBar has enabled commit/rollback buttons and AB_TABLE displays the row. But performing a commit does nothing. With the following statement after insertRow(newRow) the new row is created in the database:
    newRow.setAttribute("BId", bRow.getAttribute("BId"));
    Please give us some help on this subject.
    Best regards
    Michael Thal

    <Another attempt to post a reply. >
    Could JDev Team please provide a BC4J/JClient sample
    that performs the following task:
    The dialog should use A_TABLE as master and AB_TABLE
    as detail. The detail displays the names associated
    with the IDs. Next to AB_TABLE should be a view of
    B_TABLE which only displays rows that are currently
    not in AB_TABLE. Two buttons are used for adding and
    removing rows in AB_TABLE. After adding or removing
    rows in the intersection the B_TABLE view should be
    updated. The whole thing should work in the middle
    and client tier. This means no database round trips
    after each add/remove, no posts for AB_TABLE and no
    query reexecution for B_TABLE until commit/rollback.
    This is a very common szenario: For an item group
    (A_TABLE) one can select and deselect items
    (AB_TABLE) from a list of available items (B_TABLE).
    Most of JDeveloper4s wizards use this. They can
    handle multi/single selections, selections from
    complex structures like trees and so on. Ok, the
    wizards are not based on BC4J - or? How can we do it
    with BC4J?
    Our main problems are:
    1. Updating the view of B_TABLE after add/remove
    reflecting the current selectionYou should be able to use insertRow() to insert the row into proper collection.
    However to remove a row only from the collection, you need to add a method on the VO subclasses (and perhaps export this method so that the client side should see it) to unlink a row from a collection (but not remove the associated entities from the cache).
    This new method should use ViewRowSetImpl.removeRowAt() method to remove the row entry at the given index from it's collection. Note that this is an absolute index and not a range index in the collection.
    2. A good strategy for displaying the names instead
    of the IDs (subqueries or joining the three tables)You should join the three tables by using reference (and perhaps readonly) entities.
    3. A JBO-27101 DeadEntityAccessException when
    removing an existing row from AB_TABLE and adding it
    againThis is happening due to remove() method on the Row which is marking the row as removed. Attempts to add this row into another collection will throw a DeadEntityAccessException.
    You may 'remove the row from it's collection, then call 'Row.refresh' on it to revert the entity back to undeleted state.
    >
    Other problems:
    4. We get a JBO-25030 InvalidOwnerException when
    creating a row in AB_TABLE. This is caused by the
    composition. We workaround this using
    createAndInitRow(AttributeList) on the view object
    (instead of create()). This is our add-Action:
    ViewObject abVO =
    O =
    panelBinding.getApplicationModule().findViewObject("AB
    iew");
    ViewObject bVO =
    O =
    panelBinding.getApplicationModule().findViewObject("BV
    ew");
    Row bRow = bVO.getCurrentRow();
    NameValuePairs attribList = new NameValuePairs(
    new String[]{"BId"}, new
    String[]{"BId"}, new
    Object[]{bRow.getAttribute("BId")});
    Row newRow = abVO.createAndInitRow(attribList);
    abVO.insertRow(newRow);This is a handy approach. Note that Bc4j framework does not support dual composition where the same detail can be owned by two or more masters. In those cases, you also need to implement post ordering to post the masters before the detail (and reverse ordering for deletes).
    >
    5. After inserting the new row the NavigationBar has
    enabled commit/rollback buttons and AB_TABLE displays
    the row. But performing a commit does nothing. With
    the following statement after insertRow(newRow) the
    new row is created in the database:
    newRow.setAttribute("BId",
    d", bRow.getAttribute("BId"));This bug in JDev 903 was fixed and a patch set (9.0.3.1) is (I believe) available now via MetaLink.
    >
    >
    Please give us some help on this subject.
    Best regards
    Michael Thal

  • Many-to-many Performance Problem (Using FAQ Template)

    Having read "HOW TO: Post a SQL statement tuning request - template posting" I have gathered:
    I have included some background information at the bottom of the post
    The following SQL statement has been identified as performing poorly. It takes ~160 seconds to execute, but similar (shown below first statement) SQL statements executes in ~1 second.
    SQL taking 160 seconds:
    SELECT
    a.*
    FROM
    table_a a
    INNER JOIN table_a_b ab ON a.id = ab.media_fk
    WHERE
    ab.channel_fk IN (7, 1);SQL taking ~1 second or less
    ab.channel_fk IN (7);Or even:
    ab.channel_fk IN (6, 9, 170, 89);The purpose of the SQL is to return rows from table_a that are associated with table_b (not in SQL) through the junction table table_a_b.
    The version of the database is 10.2.0.4.0
    These are the parameters relevant to the optimizer:
    show parameter optimizer;
    NAME                                               TYPE        VALUE
    optimizer_dynamic_sampling                         integer     2
    optimizer_features_enable                          string      10.2.0.4
    optimizer_index_caching                            integer     0
    optimizer_index_cost_adj                           integer     100
    optimizer_mode                                     string      ALL_ROWS
    optimizer_secure_view_merging                      boolean     TRUE
    show parameter db_file_multi;
    NAME                                               TYPE        VALUE
    db_file_multiblock_read_count                      integer     16
    show parameter db_block_size;
    NAME                                               TYPE        VALUE
    db_file_multiblock_read_count                      integer     16
    select sname, pname, pval1, pval2 from sys.aux_stats$;
    SNAME                          PNAME                          PVAL1                  PVAL2
    SYSSTATS_INFO                  STATUS                                                COMPLETED
    SYSSTATS_INFO                  DSTART                                                07-18-2006 23:19
    SYSSTATS_INFO                  DSTOP                                                 07-25-2006 23:19
    SYSSTATS_INFO                  FLAGS                          0
    SYSSTATS_MAIN                  SREADTIM                       5.918
    SYSSTATS_MAIN                  MREADTIM                       7.889
    SYSSTATS_MAIN                  CPUSPEED                       1383
    SYSSTATS_MAIN                  MBRC                           8
    SYSSTATS_MAIN                  MAXTHR                         1457152
    SYSSTATS_MAIN                  SLAVETHR                       -1Here is the output of EXPLAIN PLAN:
    PLAN_TABLE_OUTPUT
    Plan hash value: 3781163428
    | Id  | Operation             | Name               | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT      |                    |  1352K|   771M|       | 60042   (3)| 00:05:56 |
    |*  1 |  HASH JOIN            |                    |  1352K|   771M|    27M| 60042   (3)| 00:05:56 |
    |*  2 |   INDEX FAST FULL SCAN| SYS_IOT_TOP_316310 |  1352K|    11M|       |  1816   (4)| 00:00:11 |
    |   3 |   TABLE ACCESS FULL   | TABLE_A            |  2190K|  1230M|       | 32357   (4)| 00:03:12 |
    Predicate Information (identified by operation id):
       1 - access(""AB"".""MEDIA_FK""=""A"".""ID"")
       2 - filter(""AB"".""CHANNEL_FK""=1 OR ""AB"".""CHANNEL_FK""=7)
    Note
       - 'PLAN_TABLE' is old versionFor reference, the EXPLAIN PLAN when using
    ab.channel_fk IN (6, 9, 170, 89);which executes in ~1 second is:
    PLAN_TABLE_OUTPUT
    Plan hash value: 794334170
    | Id  | Operation          | Name      | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT   |           |   143K|    81M|       | 58982   (3)| 00:05:50 |
    |*  1 |  HASH JOIN         |           |   143K|    81M|  2952K| 58982   (3)| 00:05:50 |
    |   2 |   INLIST ITERATOR  |           |       |       |       |            |          |
    |*  3 |    INDEX RANGE SCAN| C_M_INDEX |   143K|  1262K|       |  1264   (1)| 00:00:08 |
    |   4 |   TABLE ACCESS FULL| TABLE_A   |  2190K|  1230M|       | 32357   (4)| 00:03:12 |
    Predicate Information (identified by operation id):
       1 - access(""AB"".""MEDIA_FK""=""A"".""ID"")
       3 - access(""AB"".""CHANNEL_FK""=6 OR ""AB"".""CHANNEL_FK""=9 OR
                  ""AB"".""CHANNEL_FK""=89 OR ""AB"".""CHANNEL_FK""=170)
    Note
       - 'PLAN_TABLE' is old versionHere is the output of SQL*Plus AUTOTRACE including the TIMING information:
    SQL> set autotrace traceonly arraysize 100;
    SQL> SELECT
      2  a.*
      3  FROM
      4  table_a a
      5  INNER JOIN table_a_b ab ON a.id = ab.media_fk
      6  WHERE
      7  ab.channel_fk IN (7, 1);
    1336148 rows selected.
    Execution Plan
    Plan hash value: 3781163428
    | Id  | Operation             | Name               | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
    |   0 | SELECT STATEMENT      |                    |  1352K|   771M|       | 60042   (3)| 00:05:56 |
    |*  1 |  HASH JOIN            |                    |  1352K|   771M|    27M| 60042   (3)| 00:05:56 |
    |*  2 |   INDEX FAST FULL SCAN| SYS_IOT_TOP_316310 |  1352K|    11M|       |  1816   (4)| 00:00:11 |
    |   3 |   TABLE ACCESS FULL   | TABLE_A            |  2190K|  1230M|       | 32357   (4)| 00:03:12 |
    Predicate Information (identified by operation id):
       1 - access("AB"."MEDIA_FK"="A"."ID")
       2 - filter("AB"."CHANNEL_FK"=1 OR "AB"."CHANNEL_FK"=7)
    Note
       - 'PLAN_TABLE' is old version
    Statistics
          10586  recursive calls
              0  db block gets
         200457  consistent gets
         408343  physical reads
              0  redo size
      498740848  bytes sent via SQL*Net to client
         147371  bytes received via SQL*Net from client
          13363  SQL*Net roundtrips to/from client
             49  sorts (memory)
              0  sorts (disk)
        1336148  rows processedThe TKPROF output for this statement looks like the following:
    TKPROF: Release 10.2.0.4.0 - Production on Mon Oct 1 12:23:21 2012
    Copyright (c) 1982, 2007, Oracle.  All rights reserved.
    Trace file: ..._ora_4896.trc
    Sort options: default
    count    = number of times OCI procedure was executed
    cpu      = cpu time in seconds executing
    elapsed  = elapsed time in seconds executing
    disk     = number of physical reads of buffers from disk
    query    = number of buffers gotten for consistent read
    current  = number of buffers gotten in current mode (usually for update)
    rows     = number of rows processed by the fetch or execute call
    ALTER SYSTEM SET TIMED_STATISTICS = TRUE
    call     count       cpu    elapsed       disk      query    current        rows
    Parse        1      0.00       0.00          0          0          0           0
    Execute      1      0.00       0.03          0          0          0           0
    Fetch        0      0.00       0.00          0          0          0           0
    total        2      0.00       0.03          0          0          0           0
    Misses in library cache during parse: 0
    Parsing user id: 21
    SELECT
    a.*
    FROM
    table_a a
    INNER JOIN table_a_b ab ON a.id = ab.media_fk
    WHERE
    ab.channel_fk IN (7, 1)
    call     count       cpu    elapsed       disk      query    current        rows
    Parse        1      0.01       0.00          0          0          0           0
    Execute      1      0.00       0.00          0          0          0           0
    Fetch        2     27.23     163.57     179906     198394          0          16
    total        4     27.25     163.58     179906     198394          0          16
    Misses in library cache during parse: 1
    Optimizer mode: ALL_ROWS
    Parsing user id: 21
    OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
    call     count       cpu    elapsed       disk      query    current        rows
    Parse        2      0.01       0.00          0          0          0           0
    Execute      2      0.00       0.03          0          0          0           0
    Fetch        2     27.23     163.57     179906     198394          0          16
    total        6     27.25     163.62     179906     198394          0          16
    Misses in library cache during parse: 1
    OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
    call     count       cpu    elapsed       disk      query    current        rows
    Parse        0      0.00       0.00          0          0          0           0
    Execute      0      0.00       0.00          0          0          0           0
    Fetch        0      0.00       0.00          0          0          0           0
    total        0      0.00       0.00          0          0          0           0
    Misses in library cache during parse: 0
        2  user  SQL statements in session.
        0  internal SQL statements in session.
        2  SQL statements in session.
    Trace file: ..._ora_4896.trc
    Trace file compatibility: 10.01.00
    Sort options: default
           1  session in tracefile.
           2  user  SQL statements in trace file.
           0  internal SQL statements in trace file.
           2  SQL statements in trace file.
           2  unique SQL statements in trace file.
          46  lines in trace file.
         187  elapsed seconds in trace file.The DBMS_XPLAN.DISPLAY_CURSOR output:
    select * from table(dbms_xplan.display_cursor('474frsqbc1n4d', null, 'ALLSTATS LAST'));
    PLAN_TABLE_OUTPUT
    SQL_ID  474frsqbc1n4d, child number 0
    SELECT /*+ gather_plan_statistics */ c.* FROM table_a c INNER JOIN table_a_b ab ON c.id = ab.media_fk WHERE ab.channel_fk IN (7, 1)
    Plan hash value: 3781163428
    | Id  | Operation             | Name               | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  | Writes |  OMem |  1Mem | Used-Mem |
    |*  1 |  HASH JOIN            |                    |      1 |   1352K|   1050 |00:00:40.93 |     198K|    182K|    209K|    29M|  5266K| 3320K (1)|
    |*  2 |   INDEX FAST FULL SCAN| SYS_IOT_TOP_316310 |      1 |   1352K|   1336K|00:00:01.34 |   10874 |      0 |      0 |       |       |          |
    |   3 |   TABLE ACCESS FULL   | TABLE_A            |      1 |   2190K|   2267K|00:02:45.56 |     187K|    182K|      0 |       |       |          |
    Predicate Information (identified by operation id):
       1 - access(""AB"".""MEDIA_FK""=""C"".""ID"")
       2 - filter((""AB"".""CHANNEL_FK""=1 OR ""AB"".""CHANNEL_FK""=7))Thank you for reading I'm looking forward for suggestions how to improve the performance of this statement.
    h3. Backgroud
    Many years ago my company made the decision to store many-to-many relationships in our database using pipe delimited fields. An example field value:
    '|ABC|XYZ|VTR|DVD|'Each delimited value refers to a unique 'short code' in TABLE_B (There is also a true numeric foreign key in TABLE_B which is what I'm using in the junction table). We regularly search using these column with the following style SQL:
    WHERE
    INSTR(pipedcolumn, '|ABC|') > 0
    OR INSTR(pipedcolumn, '|XYZ|' > 0
    ...Appropriate indexes have been created over the years to make this process as fast a possible.
    We now have an opportunity to fix some of these design mistakes and implement junction tables to replace the piped field. Before this we decided to take a copy of a database from a customer with the largest record set and test. I created a new junction table:
    TABLE_A_B DDL:
        CREATE TABLE TABLE_A_B (
            media_fk NUMBER,
            channel_fk NUMBER,
            PRIMARY KEY (media_fk, channel_fk),
            FOREIGN KEY (media_fk) REFERENCES TABLE_A (ID),
            FOREIGN KEY (channel_fk) REFERENCES TABLE_B (ID)
        ) ORGANIZATION INDEX COMPRESS;
        CREATE INDEX C_M_INDEX ON TABLE_A_B (channel_fk, media_fk) COMPRESS;And parsing out a pipe delimited field, populated this new table.
    I then compared the performance of the following SQL:
    SELECT
    a.*
    FROM
    table_a a
    INNER JOIN table_a_b ab ON a.id = ab.media_fk
    WHERE
    ab.channel_fk IN (x, y, n); -- Can be Many Minutes
    --vs.
    SELECT
    a.*
    FROM
    table_a a
    WHERE
    INSTR(OWNERS,'|x|')    >0
    OR INSTR(OWNERS,'|y|')    >0
    OR INSTR(OWNERS,'|n|')    >0; -- About 1 second seemingly regardlessWhen x, y, n are values that occur less frequently in TABLE_A_B.CHANNEL_FK the performance is comparable. However once the frequency of x, y, n increases the performance suffers. Here is a summary of the CHANNEL_FK data in TABLE_A_B:
    --SQL For Summary Data
    SELECT channel_fk, count(channel_fk) FROM table_a_b GROUP BY channel_fk ORDER BY COUNT(channel_fk) DESC;
    CHANNEL_FK             COUNT(CHANNEL_FK)
    7                      780741
    1                      555407
    2                      422493
    3                      189493
    169                    144663
    9                      79457
    6                      53051
    171                    28401
    170                    19857
    49                     12603
    ...I've noticed that once I use any combination of values which occur more than about 800,000 times (i.e. IN (7, 1) = 780741 + 555407 = 1336148) then I get performance issues.
    I'm finding it very difficult to accept that the old pipe delimited fields are a better solution (ignoring everything other than this search criteria!).
    Thank you for reading this far. I truly look forward to suggestions on how to improve the performance of this statement.
    Edited by: user1950227 on Oct 1, 2012 12:06 PM
    Renamed link table in DDL.

    Possibly not, I followed the instructions as best as I could but may have missed things.
    h5. 1. DDL for all tables and indexes?
    h6. - TABLE_A_B is described above and has a total of 2,304,642 rows. TABLE_A and TABLE_B are described below.
    h5. 2. row counts for all tables?
    h6. - See below
    h5. 3. row counts for the predicates involved?
    h6. - Not sure what your asking for, I have a summary of data in TABLE_A_B above. Could you clarify please?
    h5. 4. Method and command used to collect stats on the tables and indexes?
    h6. - For the stats I collected above I have included the command used to collect the data. If you are asking for further data I am happy to provide it but need more information. Thanks.
    TABLE_A has 2,267,980 rows. The DLL that follows has been abbriviated, only the column involved is described.
    --  DDL for Table TABLE_A
      CREATE TABLE "NS"."TABLE_A"
       (     "ID" NUMBER
         --Lots more columns
       ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
      STORAGE(INITIAL 106496 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
      PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
      TABLESPACE "CUSTOMNAMESPACE" ;
    --  DDL for Index ID_PK
      CREATE UNIQUE INDEX "NS"."MI_PK" ON "NS"."TABLE_A" ("ID")
      PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
      STORAGE(INITIAL 16384 NEXT 29458432 MINEXTENTS 1 MAXEXTENTS 505
      PCTINCREASE 50 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
      TABLESPACE "SYSTEM" ;
    --  Constraints for Table TABLE_A
      ALTER TABLE "NS"."TABLE_A" ADD CONSTRAINT "MI_PK" PRIMARY KEY ("ID")
      USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
      STORAGE(INITIAL 16384 NEXT 29458432 MINEXTENTS 1 MAXEXTENTS 505
      PCTINCREASE 50 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
      TABLESPACE "SYSTEM"  ENABLE;
      ALTER TABLE "NS"."TABLE_A" MODIFY ("ID" NOT NULL ENABLE);TABLE_B has 22 rows. The DLL that follows has been abbriviated, only the column involved is described.
    --  DDL for Table TABLE_B
      CREATE TABLE "NS"."TABLE_B"
         "ID" NUMBER
      --Lots more columns
       ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
      STORAGE(INITIAL 106496 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
      PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
      TABLESPACE "CUSTOMNAMESPACE" ;
    --  DDL for Index CID_PK
      CREATE UNIQUE INDEX "NS"."CID_PK" ON "NS"."TABLE_B" ("ID")
      PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
      STORAGE(INITIAL 16384 NEXT 16384 MINEXTENTS 1 MAXEXTENTS 505
      PCTINCREASE 50 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
      TABLESPACE "SYSTEM" ;
    --  Constraints for Table TABLE_B
      ALTER TABLE "NS"."TABLE_B" ADD CONSTRAINT "CID_PK" PRIMARY KEY ("ID")
      USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
      STORAGE(INITIAL 16384 NEXT 16384 MINEXTENTS 1 MAXEXTENTS 505
      PCTINCREASE 50 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
      TABLESPACE "SYSTEM"  ENABLE;
      ALTER TABLE "NS"."TABLE_B" MODIFY ("ID" NOT NULL ENABLE);Edited by: davebcast on Oct 1, 2012 8:51 PM
    Index name incorrect
    Edited by: davebcast on Oct 1, 2012 8:52 PM

  • Many-to-many question

    Just asking for some help with some search terms, as I know that this topic has been argued out somewhere. I just haven't been able to find it:
    If I'm setting up a cross-reference/junction table in order to fulfill a many-to-many requirement, should I create a technical key as a primary key with a unique index on the combined foreign keys? Or should I make the combination of the foreign keys the primary key?
    Our newest standards force a technical key on all tables, and one of the Developers is asking why that's necessary on a cross-reference table. I've searched on "cross reference table primary key", "junction table primary key". Most answers suggesting a technical key are due to database performance issues that can be solved with it (not suggested for that reason for Oracle that I've found yet).
    --=Chuck

    >
    If I'm setting up a cross-reference/junction table in order to fulfill a many-to-many requirement, should I create a technical key as a primary key with a unique index on the combined foreign keys? Or should I make the combination of the foreign keys the primary key?
    >
    Assuming that each of your foreign keys is a surrogate key and not an actual data value, I have to agree with Dan on this one.
    The two primary attributes that a key value should have are: 1) it should be unique and 2) it should have no inherent meaning.
    By 'no inherent meaning' I mean it should NOT be a data value or have any meaning whatsoever attached to its value. If the value were to change it would have no impact at all on the actual data though naturally the value has to be changed the same everywhere it is used.
    A classic example in the U.S. is social security number. It should NOT be used as a key even though it might be considered a 'natural' key.
    The value is a data item that has meaning and is subject to change if for no other reason than typographical error. It is the problems involved in making changes to data items used as keys that surrogate keys are intended to prevent.
    A surrogate key (even a sequence) has no inherent meaning. If a value of 2 is being used in a system and, unknown to you, someone changes the value to a 3 everywhere in your system that it is used you will never notice it.
    I have seen no standard suggesting that multi-column surrogate keys are inappropriate. Your intersect table can use the combination of the foreign keys as the primary key and fulfill the contract of using surrogate keys.
    Sven suggested this
    >
    For example you later discover that you want a detail table for your joined table. Then the detail table would need only one column as a foreign key constraint, instead of two (which can have major performance implications).
    >
    If if was desired to meet that future requirement by using one column you can easily do so by adding a new column specifically for that purpose without any impact whatsoeve on the existing system.
    As for this possible architecture change
    >
    Or you add some third column to include into the uniqueness logic.
    >
    Well that requirement is a fundamental change to your existing one. The existing requirement is that the combination of the two foreign keys should be unique. It is not clear if Sven was suggesting that that requirement is no longer valid or if rather suggesting that there is no an ADDITIONAL requirement that those two values as well as a third should also be unique.
    If you need to implement uniqueness for the two values you currently have as well as for those combined with a third value that would be better implemented by creating yet another INTERSECT table specifically for that purpose and leave the existing intersect table in place. That architecture approach expands the data model without disrupting the existing one.
    The main design goal, in my opinion, should always be to produce a design which most easily meets current requirements without foreclosing the ability to meet unknown future requirements.

  • Many-to-many relationship - show all values

    Hi,
    I'm building a cube in 2008R2 and have a many-to-many relationship through a bridging table but when displaying the results it is effectively an inner join and I would like to see a full outer join with the unknown rows set to "unknown".
    I've managed to achieve this by doing a full outer join in the view that creates my bridging table and having an unknown member in my dimensions but then when I added in a dimension that wasn't directly related to the bridging table the unknown rows
    were removed again. I was able to get past this by adding a row to my fact table with all the keys set to unknown and the metrics set to zero.
    Whilst this works it really does not seem like an ideal solution, especially as previously empty metrics are now returning a zero.
    Is there any way to achieve this in SSAS? Perhaps in the way unknown members are processed?
    Thanks,

    cccparkhill,
    What you did is the only way to achieve what you want.
    In cubes you connect Dimensions throw Facts. By definition dimensions are
    “How do business people describe the data that
    results from the business process?”
     and facts are “What are we measuring?”, noting the underlined
    we can understand that _normally and usually_ the relation between the dimensions and the facts represent incidents happened in the real world ... the way you approach, think, and deal with dimensions and facts in cubes is different than dealing with tables
    in normal relational transnational database.
    Personally I do what you did when I want to achieve "Left join"
    Please mark this reply as the answer
    or vote as helpful, as appropriate, to make it useful for other readers

  • Many to many relationships (Again)

    Hello,
    There was a posting on above subject.
    Re: Many to many relationships between Fact and Dimension
    They asked to look chapter 3 in the user's guide... <http://download.oracle.com/docs/pdf/B10996_01.pdf>. chapter 3 talks about defining Oracle Data Objects. I could find above subject in chapter 3 .
    Here is our situation We are using OWB 9.2.0.2.8. We are in a situation to build ETL from denormalized (relational tables) source to normalized target (relational tables). It is not a data warehouse situation. It could be a reverse of data warehouse. As given below
    Supplier >--------------------<Item
    becomes Supplier ------<supp_item.>--------------Item after many to many resolution, Where supp_item is interface table.
    We were able build Supplier and Item through seprate mapping. I could build supp_item through post mapping process. I look for alternate thought as well.
    We are using separate sequence number for Supplier , Item and supp_item. The sequences will be surrogate keys such as Supplier ( Suppseq(PK)), Item (Itemseq (PK)) and supp_item(suppitemseq (PK)) Here is the sample
    Supplier
    001|S001
    002|S002
    003|S003
    004|S004
    Item
    001|I001
    002|I002
    003|I003
    Supp_item (Suppseq|ItemSeq)
    001|002 --- S001 I002
    001003 -----S001 I003
    001|004 ----- S001 I 004
    002|002 ---- S 002 I002
    002|003 ---- S 002 I003
    003|001 --- S 003 I 003
    003|003 --- S 003 I 003
    Did any body face such situation? What is the best way to create a mapping (single map or multiple map with processflow sequence) for this situation?
    Let me know the steps exercised in OWB for this situation.
    I appreciate your help.
    Regards
    Ram

    Hi Ram,
    The easiest way to do this, would be to:
    - Load supplier in one mapping and generate the surrogate key.
    - Load item another (or the same) mapping and generate the surrogate key.
    - Load supplier_item in its own separate mapping, using a key lookup (or join) to (with) the supplier and item tables.
    Needless to say, you should create unique keys on the natural key of the supplier and item tables, to enable quick index-based lookups and make sure you get one unique value for every value of the natural key.
    Hope this helps,
    Mark.

  • Working with many-to-many relationships

    I am about to start my first experience with many-to-many
    relationships using PHP and MySQL.
    My project is to create an events registration form. As you
    know, there can be many events and many participants attending many
    events.
    I am not sure on how to structure my database and tables so I
    will first show you what I have:
    create table programs (
    program_id int not null primary key auto_increment,
    program_name varchar(100) not null,
    program_date varchar(25) not null,
    program_time varchar(25) not null,
    program_coordinator varchar(100),
    program_seats int not null
    create table participants (
    participant_id int not null primary key auto_increment,
    participant_name varchar(100) not null,
    participant_phone varchar(12) not null
    I know that I need a middle table to join the two.
    create table programs_participants (
    program_id int references program(id),
    participants_id int references participants(id),
    primary key (program_id, participants_id)
    My problem is, how do I submit to both the participants AND
    the programs_participants table together? Or is this not possible?
    The participants are not already in the database when we register
    them. We enter their personal info and select their desired events
    from checkboxes on the same page.
    Thanks for your help.

    > My problem is, how do I submit to both the participants
    AND the
    > programs_participants table together? Or is this not
    possible? The
    > participants are not already in the database when we
    register them. We
    > enter
    > their personal info and select their desired events from
    checkboxes on the
    > same
    > page.
    What you need to do is a multi-step insert.
    First, you insert the new participant into the participant
    table, then use
    the @@identity command to get the uniqueID of that newly
    entered record.
    Then you can take that uniqueID to build the entry for the
    programs_participants table.
    If you use a stored procedure, you should be able to do all
    of that with
    only having to create one call to the DB from your
    Application.
    _Darrel

Maybe you are looking for

  • Installation problems with Photoshop elements on my Mac

    I try to installate PhE en Pr E; I get a message close ElementsAutoanalyser. Close Photoshopserver. But I can't find this program

  • IMovie to iWeb viewing problems

    Thanks to earlier posts I have now been able to upload a movie onto my MobileMe website, I've done this by opening it in iMovie and going to Share, Media Brower, Mobile and Publish, then doing the approprite thing in the iWeb Inspector. I have not ad

  • Oracle Applications Release 11.0 CD Pack for MS Windows NT

    1. Can I install this on Windows 2000 server? 2. If yes, when I try to install, the one hour install pops an error showing, "One hour install requires that the TCPIP Domain name is set" How do I fix this? Please help Regards Madhu

  • Pages and letters with addresses

    I'm sorry I can't find how to add names form the address book into a pages document. If this isn't built in "it is seriously missing" if it is I can't find it. I could go on but I know the device (iPad) is limited in power and memory. It just keeps g

  • Nikon D90 images not in import screen

    I recently purchased the Nikon D90 and of course I am playing with it this weekend. The images appear fine once imported into Aperture, however, the images do not appear on the import screen. At this point the images are still on the SD card in the c