473,396 Members | 2,129 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Strange join in query

prn
254 Expert 100+
Hi Folks,

Sorry if I have the forum wrong, It's more a SQL question than a SQL Server question, but it is intended to run on MS SQL Server at least. :)

I'm trying to construct a query and am having trouble wrapping my head around this so I'm hoping that someone can help me get it straight.

Here's a stripped-down version of the problem. There are 3 tables involved. (Actually 4, but I'm going to bypass one of them.)

We have a table of people -- I'll call it CUSTOMER -- that has the usual sorts of fields, e.g., CUSTOMER_ID, LAST_NAME, FIRST_NAME, EMAIL_ADDRESS, etc. Then, for reasons that I don't pretend to understand, the guy who originally wrote the application decided to put two other descriptors into a separate table. (He called them "items".) So, we have a table ITEM_TYPE that contains the fields ITEM_TYPE_ID and NAME. This table has exactly two rows for the two item types. (For simplicity, I'm going to bypass this table in the current query.) There is then another table ITEM with the fields: ITEM_ID, ITEM_TYPE_ID and NAME. The ITEM table has about 20 rows which basically are divided between the two types and a bunch of descriptors of each type to be associated to the people in the CUSTOMER table. Then there is another table CUSTOMER_TO_ITEM to associate the customers with the descriptors in ITEM. This table has fields: CUSTOMER_TO_ITEM_ID (its primary key, which is not otherwise used), CUSTOMER_ID, ITEM_ID.

The application that manages the data requires one descriptor from each item type for each customer. Therefore, each customer_id in the CUSTOMER_TO_ITEM table appears in two rows, once with an item of type 1 and once with an item of type 2. (Which, of course is why I would have made something like ITEM1_ID and ITEM2_ID fields in the CUSTOMER table, but that's neither here nor there since I don't really have a choice in the matter.)

Now I need to create a report that contains, among other things, fields from the customer table itself and BOTH item descriptions (NAMEs) and here's where I'm floundering.

Here's one version of what I've tried:
Expand|Select|Wrap|Line Numbers
  1.  
  2. SELECT    c.CUSTOMER_ID,
  3.         c.FIRST_NAME,
  4.         c.LAST_NAME,
  5.         c.EMAIL_ADDRESS,
  6.         i1.ITEM_ID,
  7.         i1.ITEM_TYPE_ID,
  8.         i1.NAME,
  9.         i2.ITEM_ID,
  10.         i2.ITEM_TYPE_ID,
  11.         i2.NAME
  12.     FROM    CUSTOMER c inner join CUSTOMER_TO_ITEM ci 
  13.             on    c.CUSTOMER_ID=ci.CUSTOMER_ID,
  14.         ITEM i1,
  15.         ITEM i2
  16.     WHERE    ci.item_id=i1.item_id
  17.         AND    ci.item_id=i2.item_id
  18.         AND    i1.item_type_id = 1
  19.         AND    i2.item_type_id = 2
  20.  
This version, as written, returns no data. If I were to remove line 16, for example, it would return thousands of rows, with a separate row for each customer with every type 2 item. If nothing else, this strongly suggests to me that my problem lies in how the joins are set up. I've tried several other ideas, trying to figure out how to inner join both i1 and i2 to ci, but I have not been able to think of one that is coherent. Everything seems to be nonsense.

Any suggestions on how to construct this query?

Thanks,
Paul
Jul 9 '08 #1
4 1109
code green
1,726 Expert 1GB
You are employing a cartesian join on ITEM table twice
Expand|Select|Wrap|Line Numbers
  1. FROM    CUSTOMER c inner join CUSTOMER_TO_ITEM ci 
  2.             on  c.CUSTOMER_ID=ci.CUSTOMER_ID,
  3.         ITEM i1,
  4.         ITEM i2
I have not studied what you are trying to do but every record is being joined to ITEM twice over.
Get rid of the commas and JOIN item ON a condition and then lets see what we have.
By the way, it is best practice to use uppercase for SQL syntax and lower case for table and field names
Jul 9 '08 #2
prn
254 Expert 100+
Thanks, code_green,

I think I'm getting closer now. If I try this query:
Expand|Select|Wrap|Line Numbers
  1. SELECT customer_id, i1.item_id AS item_id_1, i2.item_id AS item_id_2
  2. FROM item i2
  3.     INNER JOIN (item i1 
  4.         INNER JOIN customer_to_item ci 
  5.         ON i1.item_id = ci.item_id) 
  6.     ON i2.item_id = ci.item_id
  7.  
then I get something like this:
Expand|Select|Wrap|Line Numbers
  1. customer_id item_id_1  item_id_2  
  2. ----------- ---------- ---------- 
  3. 98          1          1
  4. 98          8          8
  5. 120         5          5
  6. 120         14         14
  7.  
where what I want as output is:
Expand|Select|Wrap|Line Numbers
  1. customer_id item_id_1  item_id_2  
  2. ----------- ---------- ---------- 
  3. 98          1          8
  4. 120         5          14
  5.  
What I think I need to do is to restrict the tables before the join, something like:
Expand|Select|Wrap|Line Numbers
  1. SELECT customer_id, i1.item_id AS item_id_1, i2.item_id AS item_id_2
  2. FROM item i2 WHERE i2.item_type_id = 2
  3.     INNER JOIN (item i1 WHERE i1.item_type_id = 1
  4.         INNER JOIN customer_to_item ci 
  5.         ON i1.item_id = ci.item_id) 
  6.     ON i2.item_id = ci.item_id
  7.  
except, of course, that this latter is invalid SQL syntax, but it sort of reflects the semantics that I am looking for. Any suggestions?

Thanks,
Paul

BTW, when I use code=sql, I'm still getting "Code: (text)" in the display. Am I doing something wrong? The Code tag FAQ says that "sql" should be a recognized code tag. ???
Jul 9 '08 #3
prn
254 Expert 100+
Hi again,

I think I've finally got the right way to go about it.

The answer appears to be to select from a couple of suitable subqueries, e.g.:
Expand|Select|Wrap|Line Numbers
  1. SELECT    c.customer_id,
  2.         c.first_name,
  3.         c.last_name,
  4.         c.email_address,
  5.         i1.name AS d1,
  6.         i2.name AS d2
  7. FROM    customer c,
  8.         (SELECT customer_id, name
  9.          FROM item INNER JOIN customer_to_item ci ON item.item_id=ci.item_id
  10.          WHERE item.item_type_id = 1
  11.         ) i1,
  12.         (SELECT customer_id, name
  13.          FROM item INNER JOIN customer_to_item ci ON item.item_id=ci.item_id
  14.          WHERE item.item_type_id = 2
  15.         ) i2
  16. WHERE    c.customer_id = i1.customer_id
  17.     AND c.customer_id = i2.customer_id
  18.  
Thanks, code_green and anyone else who looked at this question.

Paul
Jul 10 '08 #4
code green
1,726 Expert 1GB
I am sure this has a solution but I can't quite understand your DB structure.
A bit too wordy.
But I can do something with your 'illegal' query.
Expand|Select|Wrap|Line Numbers
  1. SELECT customer_id, i1.item_id AS item_id_1, i2.item_id AS item_id_2
  2. FROM item i2 WHERE i2.item_type_id = 2
  3.     INNER JOIN (item i1 WHERE i1.item_type_id = 1
  4.         INNER JOIN customer_to_item ci 
  5.         ON i1.item_id = ci.item_id) 
  6.     ON i2.item_id = ci.item_id
What about something like
Expand|Select|Wrap|Line Numbers
  1. SELECT customer_id, i1.item_id AS item_id_1, i2.item_id AS item_id_2
  2. FROM item i2 
  3.    INNER JOIN item i1 ON (i1.item_type_id = 1 AND i2.item_type_id = 2
  4. AND  i2.item_id = ci.item_id)
  5.         INNER JOIN customer_to_item ci 
  6.         ON i1.item_id = ci.item_id)
Although this doesn't look like it will produce a sensible result.
If you are joining to the same table twice 'item' it will probably need a GROUP BY
Jul 10 '08 #5

Sign in to post your reply or Sign up for a free account.

Similar topics

8
by: Dave | last post by:
Hi all, I've been trying to figure this out for the last day and a half and it has me stumped. I've got a web application that I wrote that keeps track of trading cards I own, and I'm moving it...
0
by: Soefara | last post by:
Dear Sirs, I am experiencing strange results when trying to optimize a LEFT JOIN on 3 tables using MySQL. Given 3 tables A, B, C such as the following: create table A ( uniqueId int not...
1
by: Vinny | last post by:
Can anyone help me with this strange problem please? I have a stored procedure, with a parameter defined as a uniqueidentifier. The procedure does a select with a number of joins, and filters...
3
by: Gary Besta | last post by:
I am trying to add a simple case statement to a stored procedure or user defined function. However when I try and save the function/procedure I get 2 syntax errors. Running the query in query...
10
by: Mark Barinstein | last post by:
Hello. W2K, db2 v7, fp11. Given: create table pays ( acode integer not null, packno smallint not null, sum decimal(15, 2) not null
16
by: Justin Koivisto | last post by:
I am trying to create a query to use as a report record source. Below is what I want to do (this was tested and works with a MySQL web script): SELECT contacts.id, contacts.email,...
2
by: veramente | last post by:
Hello all, I have the following query that has a problem i cannot resolve: SELECT puzzle_picking.*, tmagaztestate.mconto, tanagraficagen.araso, tmagaztestate.mdabol, tcausalimagaz.tdescr FROM...
8
by: Richard | last post by:
Hello! I have this piece of SQL code: UPDATE a SET Field1 = c.Field1 FROM a INNER JOIN b ON a.GUID1 = b.GUID1 INNER JOIN c ON b.GUID2 = c.GUID2 WHERE c.Type = 1
3
by: Vish4u | last post by:
Hello Everyone, I have a encountered a strange issue with the execution of my stored procedure on clients machine. My stored procedure contains a cursor in which there is a select statement...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.