I'm having a problem with my SELECT sql statement and I haven't figured it out yet. When I print out the results using mysql_fetch_assoc() function, I get repetitive rows/records. A record is repeated 13 times. I don't know why and I have done it right as far as my knowledge tells me.
The following is my sql query:
SELECT
members.member_id,
members.firstname,
members.lastname,
billing_details.Street_Address,
billing_details.Mobile_No,
orders_details.*,
food_details.*,
categories.*,
cart_details.*,
quantities.*
FROM
members, billing_details, orders_details, categories,
quantities, food_details, cart_details
WHERE
members.member_id=orders_details.member_id AND
billing_details.billing_id=orders_details.billing_id AND
orders_details.cart_id=cart_details.cart_id AND
cart_details.food_id=food_details.food_id AND
cart_details.quantity_id=quantities.quantity_id
You don't have "categories" in your WHERE clause. I am guessing you have 13 categories? If you need a better explanation, let me know.
Use SELECT DISTINCT.
Please Note
Using the mysql_* libraries is bad practise. They are Deprecated and should be replaced by either the mysqli_* libraries or a PDO object.
Why dont you make left Joins like below
SELECT members.member_id, members.firstname, members.lastname, billing_details.Street_Address, billing_details.Mobile_No, orders_details.*, food_details.*, categories.*, cart_details.*, quantities.* FROM members as m
Left join billing_details as b ON b.billing_id=m.?
LEFT JOIN orders_details as o ON o.cart_id=m.?
LEFT JOIN food_details as f ON f.f_id =m.?
LEFT JOIN cart_details as c ON c.?=?
LEFT JOIN quantitiesas q ON q.?=?
LEFT JOIN categories as cat ON cat.?=?
If you only want each member_id to appear once, you can use DISTINCT:
SELECT DISTINCT members.member_id, ...
You can also use JOIN USING to avoid repetition (DRY):
http://dev.mysql.com/doc/refman/5.7/en/join.html (search for USING(column_list))
That way, you'd also have noticed the msising predicate, since it would be right next to the joined table name.
Related
SELECT user.name, comments.cdata, comments.likes FROM comments
WHERE pid = $postNum
INNER JOIN user ON comments.uid = user.uid
ORDER BY cdate
Quick Notes:
I am a beginner, please don't be rude to me, I am trying to learn more
Yes, I have tried LEFT JOIN, but that just returns an SQL sintax error
My database is like this:
2 tables, 1 one is comments, comments has comments.cdata, comments.likes and comments.uid, the user one has the name of the user.
What I have been trying to accomplish is getting the name of the user with the comment data, instead of UID and comment data.
I also can not use 2 queries, due to me getting all the records and then displaying them on page via PHP for each.
Your query is syntactically incorrect. JOIN is an operator in the FROM clause. WHERE is a clause that follows the FROM clause.
In addition, I think the cdata and cdate should be the same thing, although I don't know what.
I also recommend using table aliases. So:
SELECT u.name, c.cdata, c.likes
FROM comments c JOIN
user u
ON c.uid = u.uid
WHERE c.pid = $postNum
ORDER BY c.cdata
I have two tables, named voter and log_vote. Voter contains data of voters while log_vote contains data of voters who have voted.
Now I'm trying to show the voters who haven't voted. I have tried using JOIN in both tables but it will fail since JOIN clause only shows voters that have voted of course.
Here's the code snippet which I've tried:
SELECT * FROM voter INNER JOIN log_vote ON log_vote.nim = voter.nim
How to show only voters who haven't voted? Is using JOIN a correct way to do? Thanks in advance, I will really appreciate for the answer!
*NOTE: I'm using PHP Technology. Wonder if there's any way that PHP can do with my problem.
This can be done with a LEFT JOIN, that way the join condition won't filter those who dont answer it, and then you filter all those who didn't have a match like this:
SELECT voter.* FROM voter
LEFT JOIN log_vote ON log_vote.nim = voter.nim
WHERE log_vote.nim is null
I think the most direct method is not exists:
select v.*
from voter v
where not exists (select 1 from log_vote lv where lv.nim = v.nim);
If you want to use join, then the appropriate version is left join:
select v.*
from voter v left join
log_vote lv
on lv.nim = v.nim
where lv.nim is null;
You can do this also..
SELECT * FROM voter LEFT JOIN log_vote ON log_vote.nim = voter.nim
WHERE log_vote.nim IS NULL
you can use
NOT IN
this code should work!
SELECT * FROM voter v WHERE v.nim NOT IN (SELECT lv.nim FROM log_vote lv)
you should give more information about the attribute of each tables are you sure they have the attribute nim in each?
Just a small MySQL Statement example:
SELECT m.nameMarket nm, m.idCity idc, c.cityname cn
FROM markets m
LEFT JOIN cities c ON m.idCity = c.idCity
works as expected. Why does neither of both work here (using the alias in the Select-Clause in the Join-Statement):
SELECT m.nameMarket nm, m.idCity idc, c.cityname cn
FROM markets m
LEFT JOIN cities c ON idc = c.idCity
OR:
SELECT m.nameMarket nm, m.idCity idc, c.cityname cn
FROM markets m
LEFT JOIN cities c ON m.idc = c.idCity
Or can I never use a column-alias in the Join Statement? (Im confused because I can also use a table-alias in the statement as done in the first SQL-code).
And second question is: Is the sequence of the statement in Left Join relevant? I.e.:
SELECT m.nameMarket nm, m.idCity idc, c.cityname cn
FROM markets m
LEFT JOIN cities c ON m.idCity = c.idCity
SELECT m.nameMarket nm, m.idCity idc, c.cityname cn
FROM markets m
LEFT JOIN cities c ON c.idCity = m.idCity
I mean the result is the same, but is there any speed/performance issue or something else related to it?
Thanks
Why does neither of both work here (using the alias in the Select-Clause in the Join-Statement)?
As you've discovered, column aliases in the SELECT clause do not work in other clauses. In some RDBMSs they work in the ORDER BY clause, and less commonly in the WHERE clause, but most often they don't. The reason is simply because the database engine doesn't look at or assign aliases in the SELECT clause until very late in the query's execution. The only exception is in subqueries.
Is the sequence of the statement in Left Join relevant?
I mean the result is the same, but is there any speed/performance issue or something else related to it?
I would expect the database engine to parse the queries exactly the same. I would go so far as to say there is a bug in the database engine if it doesn't.
Fire up the MySQL query analyzer and take a look at the execution plans with the EXPLAIN command. They should be identical.
Think about when you select something and alias it. It doesn't exist until you select it (what if it's a subset of something for example). So, does it make sense to do a join on an alias that doesn't exist yet? It's basically the last thing that's applied to the entire statement as it's ran.
A table already exists - so it makes sense to reference that with an alias. Usually however, you have to make a separate reference to refer to that table again during the query. This prevents ambiguity if you end up doing multiple joins on the same table.
And does the order matter? Well, the query optimizer will try all sorts of permutations and choose the best one. So no, it shouldn't.
I have three different SQL tables I need to join:
table "internet" with columns id|type|status
table "type_list" with columns id|type_name
table "status_list" with columns id|status_name
I want to output text from the two other tables (type_list, status_list) but not values as numbers which currently I have in table "internet".
I also don't want to make lazy programming - PHP array to make ID's equal to something like
$type_list = array("1"=>"VDSL2","2"=>"ADSL");
$status_list = array("1"=>"Pending","2"=>"Active");
because the text is already in the tables, i just dont know how to join them and output the text as query combined together in one query.
Use JOIN
SELECT i.id, type_name, status_name
FROM internet i
LEFT OUTER JOIN type_list t ON t.id = i.type
LEFT OUTER JOIN status_list s ON s.id= i.status
Read the MySQL doc for more informations.
Just write the select with the fields you want.
select internet.id,type_name,status_name from internet
inner join type_list
on type_list.id=internet.id
inner join status_list
on status_list.id=internet.id
For this you need a LEFT JOIN, like so:
SELECT i.id, t.type_name, s.status_name
FROM internet AS i
LEFT JOIN type_list AS t ON t.id = i.id
LEFT JOIN status_list AS s ON s.id= i.id
From your question, it is unclear what field you would like to join the queries on. In the above example, the queries are joined on the id field.
Please also note that the AS is not actually necessary, I have just put it in there to make it clear what is going on
I just realized that I'm going to have to start aliasing my database calls due to repeating column names in my join tables. Is there a way to automatically tell SQL to alias all my column names so that they are returned with a prefix of the table name? Otherwise it appears to be quite confusing when only some of them are aliased. Just trying to be consistent without writing tons of extra code.
$sql = "SELECT contracts.po_number, contracts.start_date, contracts.end_date, contracts.description, contracts.taa_required, contracts.account_overdue, jobs.id AS jobs_id, jobs.job_number, companies.id AS companies_id, companies.name AS companies_name
FROM contracts
LEFT JOIN jobs ON contracts.job_id = jobs.id
LEFT JOIN companies ON contracts.company_id = companies.id
WHERE contracts.id = '$id'
ORDER BY contracts.end_date";
No, but you can make life a little easier by using table aliases:
SELECT c.po_number, c.start_date, c.end_date, c.description,
c.taa_required, c.account_overdue, j.id AS jobs_id, j.job_number,
cm.id AS companies_id, cm.name AS companies_name
FROM contracts c
LEFT JOIN jobs j ON c.job_id = j.id
LEFT JOIN companies cm ON c.company_id = cm.id
WHERE c.id = '$id'
ORDER BY c.end_date
you can use alias tables in your sql statements so you have to write less, but to actually access the columns from php there's no way around aliasing all of them, if you want to access them by name.
you can also access columns with indexes from php, but that's a maintenance nightmare
I would recommend to always alias table names. It makes it very hard to read later, if you skip alias.
For info, theres a gotcha in MySQL 5.6 (possibly others!)
SELECT *
FROM table1
LEFT JOIN table2 ON PKI = FKI
works as expected.. but recently I mispelt 'LEFT' as 'LEFY' in a query and it also worked but with a standard join! so therefore
SELECT *
FROM table1
LEFY JOIN table2 ON PKI = FKI
also works just fine as does any substitute for the word LEFY, so beware a typo changing your query !!