I need to perform multiple joins on the same table. Below is my query.
When I execute following query , it gives me duplicate record for a single column.
Can anyone tell me where am I going wrong?
$result=mysql_query("SELECT DISTINCT *,CONCAT(phno, ' ', vnumber) AS source,CONCAT(phno, ' ', vnumber) AS destination FROM gcm_users as gu
INNER JOIN message_Log as ml1 ON gu.imei= ml1.Source_ID
INNER JOIN message_Log as ml2 ON gu.imei= ml2.Destination_ID
WHERE gu.id={$_SESSION['uid']}");
You can replace 2 joins with one
INNER JOIN message_Log as ml1 ON gu.imei= ml1.Source_ID
OR gu.imei= ml2.Destination_ID
Related
I am trying to SELECT data from my database with the method LEFT OUTER JOIN but when I run my syntax the result is just one row. I am sure the result must be more rows.
I also tried the method FULL OUTER JOIN instead of LEFT OUTER JOIN. But when I do that I get an syntax error.
Does someone know why I am gettin just one row?
Here is my sql syntax:
SELECT
cus.cus_id
, cus.name_cus
, cus.address, count(invoice.id) as id2
, CONCAT('€ ', ROUND(SUM(invoice.total),2)) as total
, cus.id
FROM cus
LEFT OUTER JOIN invoice
ON cus.cus_id = invoice.cus_id
You are using aggregate functions without GROUP BY clause:
SELECT
cus.cus_id
, cus.name_cus
, cus.address
, count(invoice.id) as id2
, CONCAT('€ ', ROUND(SUM(invoice.total),2)) as total
, cus.id
FROM cus
LEFT OUTER JOIN invoice ON cus.cus_id = invoice.cus_id
GROUP BY cus.cus_id, cus.name_cus, cus.address, cus.id
Although you need to group only by the unique ID (i.e. cus.id) you should add other fields that are not aggregated to GROUP BY clause as well, even though they do not create additional groups.
I have a query that I am running in MySQL, and it uses aliases to grab information from the same column twice (to and from destinations from the airport table).
`SELECT AirlineName AS 'Airline Name',
airport1.AirportName AS 'Flying From',
airport2.AirportName AS 'Flying To',
StopType AS 'Number of Stops'
FROM flightjunction
INNER JOIN airline ON flightjunction.FlightAirline = airline.AirlineID
INNER JOIN airport AS airport1 ON flightjunction.FlightFrom = airport1.AirportID
INNER JOIN airport AS airport2 ON flightjunction.FlightTo = airport2.AirportID
INNER JOIN stops ON flightjunction.FlightStops = stops.StopID;`
However, I've noticed that duplicate results are showing up when I run this query. Where am I going wrong? Thank you in advance for your help!
Since you have an inner join on the same table twice in this case, you should add a DISTINCT to eliminate duplicates.
I am using the following mysql to look at user subscriptions. I need to get all the users and in one column show if they have an active subscription or not
This is what I have tried:
SELECT `general`.`exchange`.`email`,substring_index(`general`.`exchange`.`name`, " ", 1) as name, `courses`.`courseSubscriptions`.`expiryTimestamp`
FROM `general`.`exchange`
LEFT JOIN `courses`.`courseSubscriptions`
ON `courses`.`courseSubscriptions`.`memberID` = `general`.`exchange`.`id`
WHERE (`courses`.`courseSubscriptions`.memberID = `general`.`exchange`.`id`)
AND (`courses`.`courseSubscriptions`.expiryTimestamp > 1443975741)
The problem is that it is only returning users who have a subscription. I need it to return all users, and show in a column who has a subscription or not
How can I do this?
Your where clause is turning the left join into an inner join. Also, table aliases would make the query easier to write and to read:
SELECT e.`email`, substring_index(e.`name`, ' ', 1) as name, cs.`expiryTimestamp`
FROM `general`.`exchange` e LEFT JOIN
`courses`.`courseSubscriptions` cs
ON cs.`memberID` = e.`id` AND (cs.expiryTimestamp > 1443975741) ;
The solution to the LEFT JOIN problem is to move the condition on the second table into the ON clause. Also, you don't need to repeat the join conditions.
If you want a flag, you can add that:
SELECT e.`email`, substring_index(e.`name`, ' ', 1) as name, cs.`expiryTimestamp`,
(cs.`expiryTimestamp` is not null) as isActiveFlag
FROM `general`.`exchange` e LEFT JOIN
`courses`.`courseSubscriptions` cs
ON cs.`memberID` = e.`id` AND (cs.expiryTimestamp > 1443975741) ;
You've repeated the join condition in the where clause. Since null will never return true in an equality check, this effectively removes the users without any courses and turns your outer join to an inner join. Similarly, the condition on the course's time should also be moved to the join clause:
SELECT `general`.`exchange`.`email`,
SUBSTRING_INDEX(`general`.`exchange`.`name`, " ", 1) AS name,
`courses`.`courseSubscriptions`.`expiryTimestamp`
FROM `general`.`exchange`
LEFT JOIN `courses`.`courseSubscriptions` ON
`courses`.`courseSubscriptions`.`memberID` =
`general`.`exchange`.`id` AND
`courses`.`courseSubscriptions`.expiryTimestamp > 1443975741
I have the following query:
SELECT
issue.`sequence` AS issue_sequence,
issue.`description` AS issue_description,
GROUP_CONCAT(DISTINCT(issue_category.`name`) SEPARATOR ', ') AS issue_category_name,
GROUP_CONCAT(DISTINCT(approach.`name`) SEPARATOR ', ') AS approach_name,
issue_approach.`issue_id` AS issue_approach_issue_id,
issue_approach.`approach_id` AS issue_approach_approach_id
FROM
`approach` approach
INNER JOIN `issue_approach` issue_approach ON approach.`id` = issue_approach.`approach_id`
INNER JOIN `issue` issue ON issue_approach.`issue_id` = issue.`id`
INNER JOIN `project` project ON issue.`project` = project.`id`
INNER JOIN `tenant` tenant ON project.`tenant_id` = tenant.`id`
INNER JOIN `issue_category` issue_category ON project.`id` = issue_category.`project`
INNER JOIN `user` user ON tenant.`id` = user.`tenant_id`
WHERE user.id = 1 AND project.id = 1
GROUP BY issue_category_name
ORDER BY issue_category.`name`, issue.`sequence`
I am having a problem with this line:
GROUP BY issue_category_name
Apparently, MySQL can't seem to Group by the alias for by GROUP_CONCAT result.
I am not really an expert with SQL, but is there a way I can group using the result of GROUP_CONCAT?
Sample data;
Categories: Network, Servers
Issue Id: 1
Description: Some description
Approaches: Some approaches to resolve the issue.
Basically, an issue can belong to one or many categories. I am concatenating categories for each issue. What i want to do is group the results by the result of concatenation of categories. So for example group issues whose categories are Network,Servers.
Thanks.
Im not a MySQL user, but change your group by to
Group By GROUP_CONCAT(DISTINCT(issue_category.`name`) SEPARATOR ', ')
With reference to SQL EXECUTION ORDER, the reason why this will not work is because the select statement is the last statement to be executed so that sql engine will not be knowing your column alias while grouping the records as GROUP BY occurs before SELECT. So that as Charles Bretana's answer suggests, put
Group By GROUP_CONCAT(DISTINCT(issue_category.`name`) SEPARATOR ', ')
in your group by clause. It will work fine then.
Hope this helps you.
I have the following query:
SELECT PKID, QuestionText, Type
FROM Questions
WHERE PKID IN (
SELECT FirstQuestion
FROM Batch
WHERE BatchNumber IN (
SELECT BatchNumber
FROM User
WHERE RandomString = '$key'
)
)
I've heard that sub-queries are inefficient and that joins are preferred. I can't find anything explaining how to convert a 3+ tier sub-query to join notation, however, and can't get my head around it.
Can anyone explain how to do it?
SELECT DISTINCT a.*
FROM Questions a
INNER JOIN Batch b
ON a.PKID = b.FirstQuestion
INNER JOIN User c
ON b.BatchNumber = c.BatchNumber
WHERE c.RandomString = '$key'
The reason why DISTINCT was specified is because there might be rows that matches to multiple rows on the other tables causing duplicate record on the result. But since you are only interested on records on table Questions, a DISTINCT keyword will suffice.
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
Try :
SELECT q.PKID, q.QuestionText, q.Type
FROM Questions q
INNER JOIN Batch b ON q.PKID = b.FirstQuestion
INNER JOIN User u ON u.BatchNumber = q.BatchNumber
WHERE u.RandomString = '$key'
select
q.pkid,
q.questiontext,
q.type
from user u
join batch b
on u.batchnumber = b.batchnumber
join questions q
on b.firstquestion = q.pkid
where u.randomstring = '$key'
Since your WHERE clause filters on the USER table, start with that in the FROM clause. Next, apply your joins backwards.
In order to do this correctly, you need distinct in the subquery. Otherwise, you might multiply rows in the join version:
SELECT q.PKID, q.QuestionText, q.Type
FROM Questions q join
(select distinct FirstQuestion
from Batch b join user u
on b.batchnumber = u.batchnumber and
u.RandomString = '$key'
) fq
on q.pkid = fq.FirstQuestion
As to whether the in or join version is better . . . that depends. In some cases, particularly if the fields are indexed, the in version might be fine.