My tables are like this:
Table 1 (students)
Table 2 (results)
I want to select all students from Table 1 students who have 4 results in the results table. I tried this query, but with no success:
SELECT *
FROM students
WHERE gender = 'm'
AND (SELECT COUNT( result ) AS count
FROM results
INNER JOIN students ON results.stuID = students.stuID
WHERE result !=0
) =4
ORDER BY rank ASC
You can rewrite your query by using join and HAVING clause to check the count for each student group ,This can be done without using the subquery which sometimes affects on performance
SELECT s.*,COUNT(*) AS count
FROM students s
INNER JOIN results r ON r.stuID = s.stuID
WHERE r.result !=0
GROUP BY s.stuID
HAVING count =4
ORDER BY s.rank ASC
um, that's a little convoluted.
the where clause should come after the subquery, and the subquery still needs to be JOINed back to the main query.
something like
SELECT * FROM students
INNER JOIN (SELECT COUNT(result),results.stuID as count FROM results WHERE result != 0) as result_count
ON result_count.stuID = students.stuID
WHERE result_count.count =4 AND students.gender = 'm'
ORDER BY rank ASC
You have to use alias for table also -
SELECT *
FROM students as a
WHERE gender = 'm'
AND (SELECT COUNT(result) AS count
FROM results as b
WHERE b.stuID = a.stuID AND
(result!=0 OR result IS NOT NULL OR result!='')
) = 4
ORDER BY rank ASC
Related
I have the query :
select sellers.* from sellers
left join locations
on locations.seller_id = sellers.id
group by sellers.id
limit 0, 10;
Let assume that first query gives me 10 results with a group by, 15 results without a group by.
Now I want to calculate "all results count" for the pagination.
select count(*) from ...
I tried this :
select count(*) from sellers
left join locations
on locations.seller_id = sellers.id
//group by sellers.id;
1.WITH "group by sellers.id" I get 10 results with value 1 (it should be one result with value 10)
2.WITHOUT "group by sellers.id" I get one result with value 15 (it should be one result with value 10)
any ideas?
This should work for you:
select count(*) from (select sellers.id from sellers left join locations on locations.seller_id = sellers.id) as a;
You can put your SELECT query inside a SELECT COUNT(*) query, this way:
SELECT count(*) FROM (select sellers.* from sellers
left join locations
on locations.seller_id = sellers.id
group by sellers.id) sellers;
I don't approve of your query, but you simply want the count of sellers. The simplest method is:
select count(*)
from sellers;
I have a table as follow. I want to run a query to select the data from the table using php in which if date column is repeated then I want to take only last row of that date
id Date start end publish
1 04-Nov-2015 1000 1300 0
4 04-Nov-2015 2100 3500 0
5 05-Nov-2015 1500 3000 0
like for the below table, When I run the query then the result should come:
4 04-Nov-2015 2100 3500 0
5 05-Nov-2015 1500 3000 0
When I run the query
$select = mysql_query("select * from `entry` Group by `date`") or die(mysql_error());
Then It shows the first row of repeating table, What should I modify in the query that the result should show the last row of repeating colum
Select * from (Select * from entry order by date,id desc) x group by x.date
You can do this with this approach:
$select = mysql_query("select * from `entry` Group by `date`" ORDER BY id DESC LIMIT 1) or die(mysql_error());
Try inner query, I'm not sure following will work exactly as I cant test that now, but for getting result you have to use inner query. Inner query help me to get expected result in my case.
SELECT *
FROM entry p
WHERE id =
(SELECT max(id) FROM entry p2
WHERE p2.id = p.id)
GROUP BY p.date
ORDER BY p.id DESC;
This query will work for you:
create TABLE test (id INT PRIMARY KEY, tdate DATE, start INT);
SELECT t1.* FROM test as t1
LEFT JOIN test as t2
ON (t1.tdate = t2.tdate AND t1.id < t2.id)
WHERE t2.id IS NULL;
Try this query :-
select * from( select * from entry order by id DESC ) new Group by date
I have two tables,
TABLE 1 has many of each client and campaign and is very large
TABLE 2 has only one of each client and campaign and is small.
So I want to get the lastest(highest ID) from TABLE 1 where it matches the client and campaign in TABLE 2 and only one of each.
I have tried MAX, and playing with the order by etc, but cant get it working....
The results I get are choosing the lowest ID from TABLE 1 (I want highest)
$result2 = mysql_query("SELECT table1.client,table1.campaign,table1.id
FROM table1
LEFT OUTER JOIN
table2
ON (table2.client = table1.client)
AND (table2.campaign = table1.campaign )
WHERE (table2.enabled != 'disabled')
group by campaign asc
order by client,campaign,id asc
");
Help needed....
SELECT * FROM table1
INNER JOIN
(
SELECT MAX(table1.id) AS id FROM table1
INNER JOIN table2 ON table2.client = table1.client AND table2.campaign=table1.campaign and table2.enabled != 'disabled'
GROUP BY table1.client, table1.campaign
) AS m ON m.id = table1.id
I think that's what you're asking for. For each combination of client and campaign that exists in each table, it will give you the highest ID in table 1.
I have a table categories and table posts . I want to return categories that have more than 3 posts.
My query
SELECT `categories`.`category_title`, COUNT(posts.post_id) as total_posts
FROM (`categories`)
JOIN `posts` ON `posts`.`category_id` = `categories`.`category_id`
HAVING `total_posts` > 3
ORDER BY `categories`.`date_created` desc
it returns just 1 row.. What is the correct way to do this type of query without using 2 queries?
Your query is making use of a MySQL feature called "hidden columns" and you might not even know it. This is because your query is referencing elements, such as date_created, which should be aggregated but are not ("should" here means according to the SQL standard and most other databases).
The problem with your query is that it is missing the group by. An alternative way of writing this is with the aggregation in a subquery, before joining to category:
SELECT `categories`.`category_title`, total_posts
FROM `categories` JOIN
(select categoryid, COUNT(posts.post_id) as total_posts
from `posts`
group by categoryid
having count(*) > 3
) pc
ON `pc`.`category_id` = `categories`.`category_id`
ORDER BY `categories`.`date_created` desc
You need to group the items by category.
SELECT `categories`.`category_title`, COUNT(posts.post_id) as total_posts
FROM (`categories`)
JOIN `posts` ON `posts`.`category_id` = `categories`.`category_id`
GROUP BY `categories`.`category_id`
HAVING `total_posts` > 3
ORDER BY `categories`.`date_created` desc
I currently have this left join as part of a query:
LEFT JOIN movies t3 ON t1.movie_id = t3.movie_id AND t3.popularity = 0
The trouble is that if there are several movies with the same name and same popularity (don't ask, it just is that way :-) ) then duplicate results are returned.
All that to say, I would like to limit the result of the left join to one.
I tried this:
LEFT JOIN
(SELECT t3.movie_name FROM movies t3 WHERE t3.popularity = 0 LIMIT 1)
ON t1.movie_id = t3.movie_id AND t3.popularity = 0
The second query dies with the error:
Every derived table must have its own alias
I know what I'm asking is slightly vague since I'm not providing the full query, but is what I'm asking generally possible?
The error is clear -- you just need to create an alias for the subquery following its closing ) and use it in your ON clause since every table, derived or real, must have its own identifier. Then, you'll need to include movie_id in the subquery's select list to be able to join on it. Since the subquery already includes WHERE popularity = 0, you don't need to include it in the join's ON clause.
LEFT JOIN (
SELECT
movie_id,
movie_name
FROM movies
WHERE popularity = 0
ORDER BY movie_name
LIMIT 1
) the_alias ON t1.movie_id = the_alias.movie_id
If you are using one of these columns in the outer SELECT, reference it via the_alias.movie_name for example.
Update after understanding the requirement better:
To get one per group to join against, you can use an aggregate MAX() or MIN() on the movie_id and group it in the subquery. No subquery LIMIT is then necessary -- you'll receive the first movie_id per name withMIN() or the last with MAX().
LEFT JOIN (
SELECT
movie_name,
MIN(movie_id) AS movie_id
FROM movies
WHERE popularity = 0
GROUP BY movie_name
) the_alias ON t1.movie_id = the_alias.movie_id
LEFT JOIN movies as m ON m.id = (
SELECT id FROM movies mm WHERE mm.movie_id = t1.movie_id
ORDER BY mm.id DESC
LIMIT 1
)
you could try to add GROUP BY t3.movie_id to the first query
Try this:
LEFT JOIN
(
SELECT t3.movie_name, t3.popularity
FROM movies t3 WHERE t3.popularity = 0 LIMIT 1
) XX
ON t1.movie_id = XX.movie_id AND XX.popularity = 0
On MySQL 5.7+ use ANY_VALUE & GROUP_BY:
SELECT t1.id,t1.movie_name, ANY_VALUE(t3.popularity) popularity
FROM t1
LEFT JOIN t3 ON (t3.movie_id=t1.movie_id AND t3.popularity=0)
GROUP BY t1.id
more info
LEFT JOIN only first row
https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html
Easy solution to left join the 1 most/least recent row is using select over ON phrase
SELECT A.ID, A.Name, B.Content
FROM A
LEFT JOIN B
ON A.id = (SELECT MAX(id) FROM B WHERE id = A.id)
Where A.id is the auto-incremental primary key.
LEFT JOIN (
SELECT id,movie_name FROM movies GROUP BY id
) as m ON (
m.id = x.id
)
// Mysql
SELECT SUM(db.item_sales_nsv) as total FROM app_product_hqsales_otc as db
LEFT JOIN app_item_target_otc as it ON
db.id = (SELECT MAX(id) FROM app_item_target_otc as ot WHERE id = db.id)
and db.head_quarter = it.hqcode
AND db.aaina_item_code = it.aaina_item_code AND db.month = it.month
AND db.year = it.year
WHERE db.head_quarter = 'WIN001' AND db.month = '5' AND db.year = '2022' AND db.status = '1'