I've a question about a SQL query.. I'm building a prototype webshop in ASP.NET Visual Studio. Now I'm looking for a solution to view my products. I've build a database in MS Access, it consists of multiple tables.
The tables which are important for my question are:
Product
Productfoto
Foto
Below you'll see the relations between the tables
For me it is important to get three datatypes: Product title, price and image.
The product title, and the price are in the Product table. The images are in the Foto table.
Because a product can have more than one picture, there is a N - M relation between them. So I've to split it up, I did it in the Productfoto table.
So the connection between them is:
product.artikelnummer -> productfoto.artikelnummer
productfoto.foto_id -> foto.foto_id
Then I can read the filename (in the database: foto.bestandnaam)
I've created the first inner join, and tested it in Access, this works:
SELECT titel, prijs, foto_id
FROM Product
INNER JOIN Productfoto
ON product.artikelnummer = productfoto.artikelnummer
But I need another INNER JOIN, how could I create that? I guess something like this (this one will give me an error)
SELECT titel, prijs, bestandnaam
FROM Product
(( INNER JOIN Productfoto ON product.artikelnummer = productfoto.artikkelnummer )
INNER JOIN foto ON productfoto.foto_id = foto.foto_id)
Can anyone help me?
something like this should work:
SELECT Product.titel, Product.prijs, Foto.bestandnaam FROM Product INNER JOIN
(Foto INNER JOIN Productfoto ON Foto.[foto_id] = Productfoto.[foto_id]) ON
Product.[artikelnummer] = Productfoto.[artikelnummer];
One thing about the use of linking tables
The ProductFoto table allows for N-M relations between Product and Foto indeed. Is this what you really want/need? In other words, can one Foto belong to more than one Product? If not, put the Product_Id on the Foto table. If so,...
...let's discuss JOIN.
Say we have two tables, A and B. doing a
SELECT * FROM A, B
will give you all permutations of A's rows with B's rows. We could limit the resultset by adding a WHERE clause, like WHERE A.a='lekker hoor!', or a way cooler WHERE A.id=B.a_id. Which actually starts to look like a JOIN result!
Lets do a proper JOIN then:
SELECT * FROM A JOIN B ON A.id=B.a_id
JOINs actually come in LEFT OUTER, RIGHT OUTER and FULL INNER or FULL OUTER joins.
A LEFT JOIN (use of OUTER is optional) will contain all records in the left (first) table, even if there is no corresponding records(s) in the right (second) table.
A RIGHT JOIN obviously works the same way, but mirrored.
With a FULL OUTER JOIN both tables are optional (not quite the same as SELECT * FROM A, B though!).
A FULL INNER needs matching records from both tables (this is the default).
When you do want to do more than one JOIN, say
SELECT * FROM
A
JOIN B ON A.id=B.a_id
JOIN C ON B.id=C.b_id
You can think of the extra JOIN as joining on an intermediate table, formed by joining A and B, especially when mixing some LEFT/RIGHT/INNER/OUTER JOINs.
As to your question
Use something along the lines of
SELECT TOP (1) titel, prijs, bestandnaam
FROM
( -- this bracket is MS Access specific (and awkward)
Product
INNER JOIN Productfoto ON product.artikelnummer = productfoto.artikelnummer
) -- this one too
INNER JOIN foto ON productfoto.foto_id = foto.foto_id
to satisfy MS Access, use brackets around first two tables, see Ms-Access: Join 3 Tables
Normally no brackets required (you'll get to use them like this when you discover sexy sub-selects, for which the rule is: only use them if there is no alternative).
Because there are multiple matches in your ProductFoto table, there are multiple matches in your result. Use TOP 1 (or LIMIT 1, depending on your DB) to 'fix' this.
Veel success, en doe jezelf een plezier en switch to English!
Related
I have three table, table a, b, c
table a does not have any link with table c, table b have one same column in table a and one column same as in table c
How to display data in table a by filtering the two column from table a and table B, table b and c
If you just want to filter a, I would recommend exists:
select a.*
from a
where exists (select 1
from b join
c
on b.colb = c.colb
where b.cola = a.cola
);
The advantage of this approach over join is that it does not return duplicate values when there are multiple matches. Your question specifies that you want to "display a" filtered by the other tables. This does exactly what you are specifying.
Two JOINs would achieve what you want efficiently. For instance:
SELECT TableA.Value1,
TableA.Value2
FROM TableA
JOIN TableB
ON TableB.KeyColumn = TableA.TableBKey
JOIN TableC
ON TableC.KeyColumn = TableB.TableCKey
This returns records in TableA with a reference to a record in TableB, which in turn has a reference to a record in TableC
There are other alternatives using LEFT JOIN (return all records in TableA, and referenced records from TableB if they exist, as opposed to only records in TableA that reference records in TableB), and OUTER JOIN etc
Wikipedia actually has some decent JOIN documentation, along with good explanatory Venn diagrams.
I recently asked a question on StackOverflow (MySQL Returns All Rows When field = 0) regarding a query statement not working in MySQL. I now have a very similar problem, this time using OleDB where I am trying to use a join to include fields that have 0 as an entry, but not select every field in the table as a result.
The new look MySQL query posted in the above question as the accepted answer works without a hitch. However the OleDB counterpart I have written to do almost the same does not. It's a bit messy as the tables are not named very well (I didn't create this database) and I'm getting a simple syntax error;
myQuery.CommandText = "SELECT s.scm_num, s.scm_name, c.cr3_text, q.qsp_value, s.scm_bprefix, s.scm_nxbnum FROM qspreset q INNER JOIN sdccomp s LEFT OUTER JOIN cntref3 c ON s.scm_cntref3=c.cr3_id AND q.qsp_relat=s.scm_invtype AND q.qsp_what=13";
I'm querying another table here as well as the two involved in the LEFT OUTER JOIN and I believe that is where I am making the mistake.
Join conditions need to be with the join
myQuery.CommandText =
"SELECT s.scm_num, s.scm_name, c.cr3_text, q.qsp_value, s.scm_bprefix, s.scm_nxbnum
FROM qspreset q
INNER JOIN sdccomp s
on q.qsp_relat = s.scm_invtype AND q.qsp_what = 13
LEFT OUTER JOIN cntref3 c
ON s.scm_cntref3 = c.cr3_id";
q.qsp_what = 13 can be moved to a where
I happen to like this style
In the case of MSSQL T-SQL and some queries with a lot of joins I have gotten more efficient query plan by moving a where condition up into a join. The filter happened early rather that last.
If you don't believe you can put a hard value in a join see SQLfiddle
I have a c# project where I am using a MS access database, and I am trying to put some items from two (related) tables, in the same listView.
This is the code that I have:
Where it sais "none" is the place where I want to put an item from the other table, but i don't know how. Since they have a relationship I thought that was possible to call items from one table or another.
Please note that I am fairly new to c# and working with databases.
You should join the two tables together to get the unified result.
You could do something like this:
select c.*
, s.otherFieldYouNeed
from ClientsT c
join SomeOtherTable s
on c.someId = s.someId
since the two table are related you can use a join query to get the desired result:
select FirstName,LastName,'none',CellPhone,ClientID from Clients inner join mySecondTable
on Clients.mysharedField=mySecondTable.mysharedField
select FirstName,LastName,(select none from SecondTable where Clients.Field= SecondTable.Field),CellPhone,ClientID from Clients
Try altering your query to include this information. Something like:
Select FirstName, LastName, ColumnFromOtherTable, CellPhone, ClientsT.ClientID
from ClientsT, OtherTable where ClientsT.ClientID=OtherTable.ClientID
Of course, in order to do this, you have to have a corresponding ID field in both tables.
I have a table called deliveries with columns id,shiftid, occurrence,delfee). I have three other tables delcash,delcc,delsplit. Del cash has columns (id,cost,paid), delcc has columns (id,cccost,ccpaid,cashtip), delsplit has columns(id,cashcost,cashpaid,cccost,ccpaid). The id links the delivery entries to one of the three other tables based on the type of payment. I am trying to get a list where the tables are joined together in a way so i can iterate through a list and get a table in a view that shows each delivery in order of occurrence as well as the tip and delivery fee of each delivery. Any idea if it is possible to do this? Or should I just use SQL?
SELECT deliveries.occurrence, deliveries.delfee,delcash.cost,delcash.paid,delcc.cost,delcc.paid,delcc.cashtip,
delsplit.cashcost,delsplit.cashpaid,delsplit.cccost,delsplit.ccpaid
FROM deliveries
LEFT JOIN delcash
ON deliveries.id = delcash.id
LEFT JOIN delcc
ON deliveries.id = delcc.id
LEFT JOIN delsplit
ON deliveries.id = delsplit.id
You can make a new class and let the three cost tables inherit from this class then you can apply the Table per Concrete Type strategy for mapping the tables.
see:
http://weblogs.asp.net/manavi/archive/2010/12/24/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-1-table-per-hierarchy-tph.aspx
OR redesign your database and apply Table per type strategy.
Try something like this:
var joinedDel = from delivery in tblDeliveries
join delC in tblDelCash on delivery.id equals delC.id
join delCC in tblDelCreditCard on delivery.id equals delCC.id
join delSplit in tblDelSplit on delivery.id equals delSplit.id
select new {
//Then create a new instance of Anonymous object where you will set all values of its properties
//For example, you can set ShiftID = delivery.ShiftID
};
I will also suggest to normalize first your tables(see this link for your reference) . This will give you more understanding on how will you join those tables properly.
I have two listboxes,listbox1 and listbox2, and two tables in a DB, table1 and table2. Both tables contain a column called 'Colour'. I want to display all 'Colours' from table1 in listbox1 which I‘m able to do. But in listbox2 I want to display 'Colours' from Table2 but it must not be present in the Table1 'Colours'. So how do I write a query for it?
This is what I have been trying and its not working:
SELECT Table2.Colour
FROM Table1 CROSS JOIN Table2
WHERE (Tabel1.Colour! = Table2.colour)
Error Message is — multi-part identifier Tabel2.Colour could not be found
This should work with a LEFT JOIN:
SELECT Table2.Colour
FROM Table2
LEFT JOIN Table1 ON Tabel1.Colour = Table2.colour
WHERE Table1.Colour IS NULL
You could also use NOT IN or NOT EXISTS, I just prefer the LEFT JOIN / IS NULL syntax.
For example:
SELECT Colour
FROM Table2
WHERE Colour NOT IN (SELECT Colour FROM Table1)
If your version of RDBMS implements EXCEPT clause,
you can do the following:
SELECT Colour FROM Table2
EXCEPT
SELECT Colour FROM Table1
I'm not saying that this is better than JOIN. Just another option.