mysql query on left join where multiple value - mysql

Here is my sql data fiddler http://sqlfiddle.com/#!2/63178/1. Waht's wrong with my query?
SELECT DISTINCT curr.id,curr.curr_tittle, curr.curr_desc
FROM wp_curriculum curr LEFT JOIN (SELECT DISTINCT * FROM wp_curriculum_topic WHERE curr_topic IN (4,12)) AS A ON A.curr_id = curr.id ORDER BY A.id

If you are looking for matching row from both the table then just replace LEFT JOIN to INNER JOIN, otherwise your sql query is showing expected result for LEFT JOIN condition.
SQL Query with INNER JOIN:
SELECT DISTINCT curr.id,curr.curr_tittle, curr.curr_desc FROM wp_curriculum curr INNER JOIN (SELECT DISTINCT * FROM wp_curriculum_topic WHERE curr_topic IN (4,12)) AS A ON curr.id = A.curr_id ORDER BY A.id

Your query works as expected. Could it be you are mixing ID and CURR_ID?

Related

LEFT OUTER JOIN get max() and include NULL values

I've managed to get the data out and include NULL values by using left outer join. This is my current query:
select s.user, a.id, a.datetime as date, a.total_time
from steam_accounts s
left outer join activity a on a.steam_id = s.id
where s.user_id = 1
This returns this:
Which is almost perfect. But now I need to filter the results with max(a.id) and include null values if there are no matches from the outer join.
Here's what I've tried:
select s.id, s.user, max(a.id), a.datetime as date, a.total_time
from steam_accounts s
left outer join activity a on a.steam_id = s.id
where s.user_id = "1"
Result:
All the null values disappeared. I only wanted to filter out the first two results from the previous query.
This is my desired result:
Any much is much appreciated. Thanks
Alas, MySQL doesn't have OUTER APPLY or LATERAL JOIN, so it will be less efficient, than it could have been. It seems that something like this should produce what you want:
SELECT
s.id
,s.user
,ActivityIDs.MaxActivityID
,activity.datetime as date
,activity.total_time
FROM
steam_accounts s
LEFT JOIN
(
SELECT
a.steam_id
,max(a.id) AS MaxActivityID
FROM activity a
GROUP BY a.steam_id
) AS ActivityIDs
ON ActivityIDs.steam_id = s.id
LEFT JOIN activity ON
activity.id = ActivityIDs.MaxActivityID
WHERE
s.user_id = 1
For each steam_account we find one activity with max ID in the first LEFT JOIN. Then we fetch the rest of activity details using found ID in the second LEFT JOIN.
Use max(coalesce(a.id, 0))
Any aggregation done on results with null will always return null
What I can think of would be using ROW_NUMBER() with partitioning functionality as in SQL Server or PostgreSQL. There's an example how to do this in MySQL here:
http://blog.sqlauthority.com/2014/03/09/mysql-reset-row-number-for-each-group-partition-by-row-number/.
What comes next, I'd partition your result set by user and sort it by date DESCENDING and then take records where ROW_NUMBER is equals to 1.
I've given similar answer here using SQL Server functionality: https://stackoverflow.com/a/30952154/3680098
It should produce you result set as follows:
Use aggregation to calculate the maximum value. Then join in that record using another left join:
select s.user, a.id, a.datetime as date, a.total_time
from steam_accounts s left outer join
activity a
on a.steam_id = s.id left outer join
(select a.steam_id, max(a.id) as maxid
from activity a
group by a.steam_id
) amax
on amax.steam_id = a.steam_id and amax.maxid = a.id
where s.user_id = 1;

Mysql Nested/Multiple Query handling

I have three queries gives me result individually correct but my requirement is i need all result in single query only so how should i proceed?
select * from user_post_like
inner join user_post on user_post_like.postID = user_post.postID
inner join Users on Users.userID=user_post_like.userID
where (user_post.poster='$uid' AND user_post_like.userID!='$uid')
ORDER BY likeID DESC;
select * from user_post_comment
inner join user_post on user_post_comment.postID = user_post.postID
inner join Users on Users.userID=user_post_comment.commenter
where (user_post.poster='$uid' AND user_post_comment.commenter!='$uid')
ORDER BY commentID DESC;
select * from user_post_share
inner join user_post on user_post_share.postID = user_post.postID
inner join Users on Users.userID=user_post_share.Share_user_id
where (user_post.poster='$uid' AND user_post_share.Share_user_id!='$uid')
ORDER BY shareID DESC;
Since you're joining the tables anyway, you can put columns from all in your select - and keep your statement readable. If you have duplicate column names (from different tables) you may need to aggregate them with functions and group by.
SELECT s.*, p.*, u.*
FROM user_post_share s
INNER JOIN user_post p ON s.postID = p.postID
INNER JOIN Users u ON u.userID = p.poster
WHERE (p.poster='$uid' AND s.Share_user_id != '$uid')
ORDER BY shareID DESC
try sumthing like this
select * from user_post_like,user_post_comment,user_post_share <inner joins> <where conditions>

How to add where clause in access join query

I have query like this.
SELECT account.AccountNumber, account.Name, Sum(agro.price*agro.qty) AS Expr1
FROM account,data INNER JOIN (agro INNER JOIN data ON agro.BillNo = data.BillNo) ON
account.AccountNumber = data.acno
GROUP BY account.AccountNumber, account.Name;
I want to add where db='true' this columns is of 'data' table then how can i do pls help me?
Try this:
SELECT account.AccountNumber, account.NAME, Sum(agro.price * agro.qty) AS Expr1
FROM ((account
INNER JOIN data ON account.AccountNumber = data.acno)
INNER JOIN agro ON agro.BillNo = data.BillNo)
WHERE data.db='true'
GROUP BY account.AccountNumber, account.NAME;
You had some confusion in your JOINs, but i think this is what you were aiming for

How do I write a My(SQL) query that counts from multiple tables based on specific WHERE clause criteria

I have 5 tables: a, b, c, d and e.
Each table is joined by an INNER JOIN on the id field.
My query is working perfectly fine as it is but I need to enhance it to count the result so I can echo it to the screen. I have not been able to get the count working.
There are very specific fields I am querying:
state_nm
status
loc_type
These are all parameters I enter manually into the query like so:
$_POST["state_nm"] = 'AZ'; ... // and for all other below values..
SELECT *
FROM main_table AS a
INNER JOIN table_1 AS b ON a.id = b.id
INNER JOIN table_2 AS c ON b.id = c.id
INNER JOIN blm table_3 AS d ON c.id = d.id
INNER JOIN table_4 AS e ON d.id = e.id
WHERE a.trq != ''
AND b.state_nm = '".$_POST["state_nm"]."'
AND b.loc_type LIKE \ "%".$_ POST ["loc_type"]."%\"
AND b.STATUS = '".$_POST["status"]."'
GROUP BY b.NAME
ORDER BY c.county ASC;
not sure I get exactly what is your goal here.
anyway, using "select *" and group by in the same query is not recommended and in some databases will raise an error
what I would do is something like that:
select a.name, count(*) from (
SELECT * FROM main_table as a
INNER JOIN table_1 as b
ON a.id=b.id
INNER JOIN table_2 as c
ON b.id=c.id
INNER JOIN blm table_3 as d
ON c.id=d.id
INNER JOIN table_4 as e
ON d.id=e.id
WHERE a.trq != ''
AND b.state_nm = '".$_POST["state_nm"]."'
AND b.loc_type LIKE \"%".$_POST["loc_type"]."%\"
AND b.status = '".$_POST["status"]."'
)a
group by a.name
the basic idea is to add an outer query and use group by on it...
hopefully this solves your problem.
In place of
SELECT *
in your query, you could replace that with
SELECT COUNT(*)
That query should return the number of rows that would be in the resultset for the query using SELECT *. Pretty easy to test, and compare the results.
I think that answers the question you asked. If not, I didn't understand your question.
I didn't notice the GROUP BY in your query.
If you want to get a count of rows returned by that query, wrap it in outer query.
SELECT COUNT(1) FROM (
/* your query here */
) c
That will give you a count of rows returned by your query.

MySQL inner join different results

I am trying to work out why the following two queries return different results:
SELECT DISTINCT i.id, i.date
FROM `tblinvoices` i
INNER JOIN `tblinvoiceitems` it ON it.userid=i.userid
INNER JOIN `tblcustomfieldsvalues` cf ON it.relid=cf.relid
WHERE i.`tax` = 0
AND i.`date` BETWEEN '2012-07-01' AND '2012-09-31'
and
SELECT DISTINCT i.id, i.date
FROM `tblinvoices` i
WHERE i.`tax` = 0
AND i.`date` BETWEEN '2012-07-01' AND '2012-09-31'
Obviously the difference is the inner join here, but I don't understand why the one with the inner join is returning less results than the one without it, I would have thought since I didn't do any cross table references they should return the same results.
The final query I am working towards is
SELECT DISTINCT i.id, i.date
FROM `tblinvoices` i
INNER JOIN `tblinvoiceitems` it ON it.userid=i.userid
INNER JOIN `tblcustomfieldsvalues` cf ON it.relid=cf.relid
WHERE cf.`fieldid` =5
AND cf.`value`
REGEXP '[A-Za-z]'
AND i.`tax` = 0
AND i.`date` BETWEEN '2012-07-01' AND '2012-09-31'
But because of the different results that seem incorrect when I add the inner join (it removes some results that should be valid) it's not working at present, thanks.
INNER JOIN statement will retrieve rows that are stored in both table of the jion statement.
Try a LEFT JOIN statement. This will return rows that are in first table but not necessary in the second one :
SELECT DISTINCT i.id, i.date
FROM `tblinvoices` i
LEFT JOIN `tblinvoiceitems` it ON it.userid=i.userid
LEFT JOIN `tblcustomfieldsvalues` cf ON it.relid=cf.relid
WHERE i.`tax` = 0
AND i.`date` BETWEEN '2012-07-01' AND '2012-09-31'
INNER JOIN means show only records where the same ID value exists in both tables.
LEFT JOIN means to show all records from left table (i.e. the one that precedes in SQL statement) regardless of the existance of matching records in the right table.
Try LEFT Join instead of INNER JOIN
SELECT DISTINCT i.id, i.date
FROM `tblinvoices` i
LEFT JOIN `tblinvoiceitems` it ON it.userid=i.userid
LEFT JOIN `tblcustomfieldsvalues` cf ON it.relid=cf.relid
WHERE i.`tax` = 0
AND i.`date` BETWEEN '2012-07-01' AND '2012-09-31'