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: -
-
SELECT c.CUSTOMER_ID,
-
c.FIRST_NAME,
-
c.LAST_NAME,
-
c.EMAIL_ADDRESS,
-
i1.ITEM_ID,
-
i1.ITEM_TYPE_ID,
-
i1.NAME,
-
i2.ITEM_ID,
-
i2.ITEM_TYPE_ID,
-
i2.NAME
-
FROM CUSTOMER c inner join CUSTOMER_TO_ITEM ci
-
on c.CUSTOMER_ID=ci.CUSTOMER_ID,
-
ITEM i1,
-
ITEM i2
-
WHERE ci.item_id=i1.item_id
-
AND ci.item_id=i2.item_id
-
AND i1.item_type_id = 1
-
AND i2.item_type_id = 2
-
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
4 1109
You are employing a cartesian join on ITEM table twice - FROM CUSTOMER c inner join CUSTOMER_TO_ITEM ci
-
on c.CUSTOMER_ID=ci.CUSTOMER_ID,
-
ITEM i1,
-
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
prn 254
Expert 100+
Thanks, code_green,
I think I'm getting closer now. If I try this query: -
SELECT customer_id, i1.item_id AS item_id_1, i2.item_id AS item_id_2
-
FROM item i2
-
INNER JOIN (item i1
-
INNER JOIN customer_to_item ci
-
ON i1.item_id = ci.item_id)
-
ON i2.item_id = ci.item_id
-
then I get something like this: -
customer_id item_id_1 item_id_2
-
----------- ---------- ----------
-
98 1 1
-
98 8 8
-
120 5 5
-
120 14 14
-
where what I want as output is: -
customer_id item_id_1 item_id_2
-
----------- ---------- ----------
-
98 1 8
-
120 5 14
-
What I think I need to do is to restrict the tables before the join, something like: -
SELECT customer_id, i1.item_id AS item_id_1, i2.item_id AS item_id_2
-
FROM item i2 WHERE i2.item_type_id = 2
-
INNER JOIN (item i1 WHERE i1.item_type_id = 1
-
INNER JOIN customer_to_item ci
-
ON i1.item_id = ci.item_id)
-
ON i2.item_id = ci.item_id
-
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. ???
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.: -
SELECT c.customer_id,
-
c.first_name,
-
c.last_name,
-
c.email_address,
-
i1.name AS d1,
-
i2.name AS d2
-
FROM customer c,
-
(SELECT customer_id, name
-
FROM item INNER JOIN customer_to_item ci ON item.item_id=ci.item_id
-
WHERE item.item_type_id = 1
-
) i1,
-
(SELECT customer_id, name
-
FROM item INNER JOIN customer_to_item ci ON item.item_id=ci.item_id
-
WHERE item.item_type_id = 2
-
) i2
-
WHERE c.customer_id = i1.customer_id
-
AND c.customer_id = i2.customer_id
-
Thanks, code_green and anyone else who looked at this question.
Paul
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. - SELECT customer_id, i1.item_id AS item_id_1, i2.item_id AS item_id_2
-
FROM item i2 WHERE i2.item_type_id = 2
-
INNER JOIN (item i1 WHERE i1.item_type_id = 1
-
INNER JOIN customer_to_item ci
-
ON i1.item_id = ci.item_id)
-
ON i2.item_id = ci.item_id
What about something like - SELECT customer_id, i1.item_id AS item_id_1, i2.item_id AS item_id_2
-
FROM item i2
-
INNER JOIN item i1 ON (i1.item_type_id = 1 AND i2.item_type_id = 2
-
AND i2.item_id = ci.item_id)
-
INNER JOIN customer_to_item ci
-
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
Sign in to post your reply or Sign up for a free account.
Similar topics
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...
|
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...
|
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...
|
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...
|
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
|
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,...
|
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...
|
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
|
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...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
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...
|
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...
|
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...
|
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,...
|
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...
|
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...
|
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,...
|
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...
| |