I tried looking for a question such as this on SO but a lot of them were outer joins with more complicated select clauses whereas my question is more simple and should be a faster reference for newbies at MySQL.
Being used to Oracle SQL, I was trying to join three tables and perform a delete like so:
DELETE * FROM tbl_login, tbl_profile, images
WHERE tbl_login.loginid = tbl_profile.loginid
AND tbl_profile.loginid = images.loginid
AND loginid = 'derek';
In MySQL my attempt is:
DELETE FROM tbl_profile, images, tbl_login
USING tbl_profile INNER JOIN images INNER JOIN tbl_login
WHERE tbl_profile.loginid = images.loginid
AND images.loginid = tbl_login.loginid
AND loginid='derek';
I ran this in the SQL section of PHPMyadmin and it told me that loginid was ambiguous which I thought was funny because if I'm joining the three tables why would it be ambiguous? So I edited it and made it
tbl_login.loginid = 'derek'
that deleted the correct row from the tbl_login table but it ended up deleting all the rows from my other tables. What am I doing wrong here?
Remove tbl_profile and images from your FROM clause.
I think your query should look something like this (note the different way the join conditions are defined):
DELETE FROM tbl_profile, images, tbl_login
USING tbl_profile INNER JOIN images ON images.loginid = tbl_profile.loginid
INNER JOIN tbl_login ON tbl_login.loginid = tbl_profile.loginid
WHERE tbl_login.loginid='derek';
I assume you want to delete the rows from all 3 tables. If you only want to delete from tbl_login, the previous answer tells you how to do it :)
Related
I need to write a query to join 3 tables.
My tables are:
ucommerce_customer
ucommerce_order
ucommerce_order_line
All 3 tables have a column called order_id.
The table ucommerce_order has a column called order_status.
When the order_status is set to "open" I want to display the order details.
ResultSet myRs = myStmt.executeQuery
("SELECT * FROM ucommerce_customer
INNER JOIN ucommerce_order
INNER JOIN ucommerce_order_line
WHERE ucommerce_order.order_status = 'open'");
My query ignores the order status and displays all orders, open and closed.
Also I have several products so ucommerce_order_line has several entries for the same order_id, my query displays duplicate entries and it duplicates the entire list as well.
How can I write a query that will show only open orders without duplicating everything?
In MySQL, the on/using clause is optional. This is very sad because someone can make mistakes like you did. Your question only mentions one column, so perhaps that is all that is needed for the join:
SELECT *
FROM ucommerce_customer INNER JOIN
ucommerce_order
USING (orderId) INNER JOIN
ucommerce_order_line
USING (OrderId)
WHERE ucommerce_order.order_status = 'open';
I would be surprised if the customer table really had a column called OrderId (seems like a bad idea in most situations), so the first USING clause might want to use CustomerId.
I would recommend to use a natural join instead. Maybe that's where the errors are coming from.
The duplicates can be removed by running SELECT DISTINCT * ...
I've created several tables in a test database based on columns/rows in my main database.
test.websites.url = main.websites.url
test.category_main = main.websites.category1
test.category_01 = main.websites.category2
test.category_02 = main.websites.category3
etc...
The test database columns already contain all the rows from the main
database, but I need to add the rows from the respective tables to the
category_to_website table and create foreign keys because there is
currently no relation between them in the test database. That is why I have joined the
main database in the query.
When trying to use the main table as a reference for updating the existing rows in the test database, some values are updated but they are not always correct. I'm executing the query from the test database.
My query:
UPDATE category_to_website
LEFT JOIN main.websites
ON websites.url = main.websites.url
LEFT JOIN category_01
ON category_01.name = main.websites.category2
SET category_to_website.category_01_id = category_01.id
WHERE category_to_website.category_01_id = main.websites.category2
My database schema:
I suspect that the issue is with the type of JOINs I am doing, but I've tried LEFT JOIN, JOIN, and INNER JOIN and get the same results. I think that maybe I need a SELECT sub query or my WHERE clause is off?
EDIT
Based on the comments I was able to get this all sorted out. Here are the steps I took.
1. Merged the category_* tables into a category table.
2. Joined the test.websites table into the query.
UPDATE test.category_to_website
LEFT JOIN test.websites
ON test.websites.id = category_to_website.url_id
RIGHT JOIN main.websites
ON test.websites.url = main.websites.url
INNER JOIN test.category
ON test.category.name = main.websites.category1
SET category_to_website.category01_id = category.id
WHERE category_to_website.url_id = test.websites.id
UPDATE category_to_website
JOIN websites
ON websites.id = category_to_website.url_id
JOIN main.websites
ON websites.url = main.websites.url
JOIN category
ON category.name = main.websites.category1
SET category_to_website.category01_id = category.id
SETs are done to rows that participate in the JOINs. But if you LEFT JOIN to category_to_website then all its rows participate so then you must restrict them in a WHERE the way you already did in the ON.
Thank goodness you have started to relationalize that horrible schema. Keep going: replace all multiple categery_ columns in each table by just one category column for id or name. And if you named them category_id and category_name their nature would be clear. (Maybe post your next version as a new question.)
In my SQL query i'm checking on different parameters. Nothing strange happens when there is data in each of the tables for the inserted tripcode. But when one table has no data in it I don't get any data at all. Even if the other tables have data. So I need to be able to check if the table has data in it and if it has, I need to select.
SELECT roadtrip_tblgeneral.*,
GROUP_CONCAT(distinct roadtrip_tblhotels.hotel) as hotels,
GROUP_CONCAT(distinct roadtrip_tbllocations.location) as locations,
GROUP_CONCAT(distinct roadtrip_tbltransports.transport) as transports
FROM roadtrip_tblgeneral
INNER JOIN roadtrip_tblhotels
ON roadtrip_tblgeneral.id = roadtrip_tblhotels.tripid
INNER JOIN roadtrip_tbllocations
ON roadtrip_tblgeneral.id = roadtrip_tbllocations.tripid
INNER JOIN roadtrip_tbltransports
ON roadtrip_tblgeneral.id = roadtrip_tbltransports.tripid
WHERE roadtrip_tblgeneral.tripcode = :tripcode
GROUP BY roadtrip_tblgeneral.id
Only the tables with the GROUP_CONCAT in front need the check. I already tried with the keyword EXISTS in front of it.
Thanks in advance.
The INNER JOIN keyword returns rows when there is at least one match in both tables. You can't have a match if there is no data, perhaps you want to use a LEFT JOIN or a FULL JOIN.
Left join will be use as it returns all the data from the table at left, even if there is no matching rows in right table
I have 2 Tables in phpmyadmin that need joining
tracklisting is my one and catelogue is the other, and are saved as innodb
They both have a column CAT.NO and would like it to be joined on this column. In catelogue it is the primary and in tracklisting it's indexed
catelogue is my parent and tracklisting would be the child as it doesn't have info for every record in catelogue. I believe this would be correct unless I'm wrong
How do I do this so that when I query on a column in tracklisting it only brings up the matches for 'catelogue' because I want to know what album it's on and not my entire 60000+ catelogue
Can this be done with phpmyadmin's interface or is this a sql statement
Many thanks
EDIT:
This was the code that worked
SELECT *
FROM tracklisting
INNER JOIN catelogue ON catelogue.`CAT NO.` = tracklisting.`TRACKLISTING CAT NO.`
WHERE tracklisting.`ARTIST` LIKE 'placebo'
Thanks to everyone that helped out
I dont know if this can be done with the interface, but with sql
SELECT *
FROM
tracklisting t
INNER JOIN catelouge c on c.catno=t.catno
WHERE t.id = 1
You can query with a LEFT JOIN:
SELECT * FROM tracklisting LEFT JOIN catelogue ON tracklisting.`CAT.NO` = catelogue.`CAT.NO` WHERE tracklisting.`<id-field>` = <id-value>`
http://dev.mysql.com/doc/refman/5.0/en/join.html
Assuming that your tracklisting has an id and you want to query with it:
select * from tracklisting t
inner join catelogue c on c.cat.no = t.cat.no
where t.id = 1
The actual join takes place in a SQL statement although with certain storage types like InnoDB you can also create foreign key references that enforce the relationship at the database level so that your inserts require the proper records to be in place and your deletes are restricted if child records exist.
Here is one way of doing the join syntax for your SQL query:
SELECT t.* FROM tracklisting t, catalogue c
WHERE `t.CAT.NO` = `c.CAT.NO`
EDIT: Here is a link to a tutorial for creating foreign keys in phpMyAdmin.
I have database with schema on picture below and I need to select everything related to one row (one id) of [letaky]. That means the related [zamestnanci], every related [obsah] and every [knihy] in it.
This is the first time i used relations in database and i have no idea how to make such a select.
Use JOIN ... ON:
SELECT *
FROM zamestnanci
JOIN lekaty ON lekaty.zamestnanciid = zamestnanci.id
JOIN obsah ON obsah.idletaku = lekaty.id
JOIN knihy ON knihy.id = obsah.idknihy
WHERE letaky.id = 123
You may also want to consider whether you need INNER JOIN, LEFT JOIN or RIGHT JOIN for each of these joins. The difference between these JOINs is described in many other questions on StackOverflow, for example this one:
SQL Join Differences