i have two tables:
1. movie
id, userid, movie_id, status, score
2. movie_data
id, name_de, name_en, description, url
When i use this query:
SELECT *
FROM `movie` LEFT JOIN
movie_data ON movie.movie_id = movie_data.id
ORDER BY movie.id
When i enter this query, i get all fields, but also two times id. But i don't manage to show only the first "id" or rename the second id. i hope someone can help me :)
Thanks for reading
You need to enumerate the columns in the SELECT clause and use aliases to disambiguate homonym columns:
SELECT
m.id,
m.user_id,
m.movie_id,
m.status,
m.score,
d.id data_id, --> column alias
d.name_de,
d.name_en,
d.description,
d.url
FROM movie m
LEFT JOIN movie_data d ON m.movie_id = d.id
ORDER BY m.id
Explicitly list the columns you want. Don't use select *:
SELECT m.id, m.userid, m.movie_id, m.status, m.score,
md.name_de, md.name_en, md.description, md.url
FROM `movie` m LEFT JOIN
movie_data md
ON m.movie_id = md.id
ORDER BY m.id
The query should be next:
SELECT
`movie`.`id`,
`movie`.`userid`,
`movie`.`movie_id`,
`movie`.`status`,
`movie`.`score`,
`movie_data`.`name_de`,
`movie_data`.`name_en`,
`movie_data`.`description`,
`movie_data`.`url`
FROM `movie`
LEFT JOIN `movie_data` ON `movie`.`movie_id` = `movie_data`.`id`
ORDER BY `movie`.`id`;
This way you can exactly select what you need
You can also do, for example
SELECT
`movie`.*, -- select all fields from one table
movie_data.id as movieId -- and some fields of another table
FROM `movie` LEFT JOIN
movie_data ON movie.movie_id = movie_data.id
ORDER BY movie.id
Related
I am trying to make a query to fetch the newest car for each user:
select * from users
left join
(select cars.* from cars
where cars.userid=users.userid
order by cars.year desc limit 1) as cars
on cars.userid=users.userid
It looks like it says Unknown column "users.userid" in where clause
I tried to remove cars.userid=users.userid part, but then it only fetches 1 newest car, and sticks it on to each user.
Is there any way to accomplish what I'm after? thanks!!
For this purpose, I usually use row_number():
select *
from users u left join
(select c.* , row_number() over (partition by c.userid order by c.year desc) as seqnum
from cars c
) c
on c.userid = u.userid and c.seqnum = 1;
One option is to filter the left join with a subquery:
select * -- better enumerate the columns here
from users u
left join cars c
on c.userid = u.userid
and c.year = (select max(c1.year) from cars c1 where c1.userid = c.userid)
For performance, consider an index on car(userid, year).
Note that this might return multiple cars per user if you have duplicate (userid, year) in cars. It would be better to have a real date rather than just the year.
Maybe there are better and more efficient way to query this. Here is my solution;
select users.userid, cars.*
from users
left join cars on cars.userid = users.userid
join (SELECT userid, MAX(year) AS maxDate
FROM cars
GROUP BY userid) as sub on cars.year = sub.maxDate;
My BD:
I need to select the column with departament.nume which have <=3 records in tabel angajat.departament_id.
i tried:
SELECT departament.nume
FROM (angajat INNER JOIN
departament
ON angajat.departament_id=departament.id_dep
)
where count(angajat.id_dep)<=3;
Aggregate before joining:
SELECT d.nume
FROM departament d LEFT JOIN
(SELECT a.departament_id, COUNT(*) as cnt
FROM angajat a
GROUP BY a.departament_id
) a
ON a.departament_id = d.id_dep
WHERE COALESCE(cnt, 0) < 3 ;
Note the use of LEFT JOIN to be sure that departments with no rows in agnajat are included in the result set.
SELECT departament.nume
FROM angajat
INNER JOIN departament
ON angajat.departament_id=departament.id_dep
GROUP BY departament.nume
HAVING COUNT(*)<=3
Use Group By and Having
SELECT d.nume,
FROM angajat a JOIN departament d ON a.departament_id = d.id_dep
GROUP BY d.nume
HAVING COUNT (d.nume) <= 3;
No need for a subquery.
SELECT departament.nume
FROM departament
LEFT JOIN angajat ON angajat.departament_id=departament.id_dep
GROUP BY departament.id_dep
HAVING COUNT(*) <= 3
If you don't want departments with no angajat records, use an inner join instead.
If you want the counting to include together departments with the same nume but different id_dep, group on nume instead.
If you don't want that, but only want each nume returned only once, select DISTINCT departament.nume.
What's wrong with my query:
SELECT
Articles.Name,
GroupOfArticles.Name,
(select GroupOfArticles.Name from GroupOfArticles
where GroupOfArticles.ParentGroup= Articles.Group)
FROM Articles
JOIN GroupOfArticles
ON Articles.Group = GroupOfArticles.ID
I want to show the name of the article and the name of the most basic group in the hierarchy...
databasemodel
You need to JOIN the subquery outside of the actual subquery like
SELECT a.Name, g.Name,
FROM Articles a
INNER JOIN (select Name,ParentGroup from GroupOfArticles) g
ON g.ID =a.Group
AND g.ParentGroup=a.group
The actual query shown can even be done without the subquery, like
SELECT a.Name, g.Name,
FROM Articles a
INNER JOIN GroupOfArticles g
ON g.ID =a.Group
AND g.ParentGroup=a.group
Although I doubt very much that you really want to join on both columns: ID and ParentGroup?
Obviously I haven't seen your schema, but I don't believe you need the sub-select at all. It appears that it would return the same as GroupOfArticles.Name does?
SELECT
Articles.Name,
GroupOfArticles.Name
FROM
Articles JOIN GroupOfArticles
ON Articles.Group = GroupOfArticles.ID
AND GroupOfArticles.ParentGroup = Articles.Group
Actually, the above assumes that every article returned will be part of a specific group, and will also have a parent group which is the same. Inception?
EDIT Based on more requirements / information, here is a second version:
SELECT DISTINCT
a.Name,
g.Name
FROM
GroupOfArticles g INNER JOIN GroupOfArticles g1
ON g1.ParentGroup = g.ID
INNER JOIN Articles a ON
CASE
WHEN g.ParentGroup IS NULL THEN g.ID
ELSE g1.ID
END
I also created an SQLFiddle for the above.
EDIT 2 An alternative version which doesn't include JOIN OR CASE:
SELECT DISTINCT
a.Name,
g.Name
FROM
Articles a, GroupOfArticles g, GroupOfArticles g1
WHERE
g.ID <> g1.ID
AND g.ParentGroup IS NULL
AND
(
a.Group = g.ID
OR a.Group = g1.ID AND g1.ParentGroup = g.ID
)
SQLFiddle
Note that in the two latest queries, you could replace the DISTINCT keyword with GROUP BY a.Name HAVING COUNT(*) > 0, If you really must use those constructs as well. Just remove DISTINCT from the top, and add the GROUP BY ... at the end.
I got the following tables:
pictures
------------------------------------
id
name
views
votes
------------------------------------
id
user_id
pic_id
I want to get a result from a query that will give me each picture id, with the views of the picture, and the total votes from the table votes for the specific pic_id
example:
pictures.id, pictures.views, total votes
1 ------------ 78------------------ 123
2 ------------ 23------------------- 69
and so on...
The code I tried:
SELECT `pictures`.`id`,`pictures`.`views`, COUNT(`votes`.`pic_id`) as votes
FROM `pictures`
JOIN `votes`
ON `pictures`.`id` = `votes`.`pic_id`
But it doesn't give me the reuslt I desire.
You need to have GROUP BY clause.
The use of LEFT JOIN will display all records on table pictures with or without matching record on table votes.
SELECT a.id, a.name, a.views,
COUNT(b.pic_id) TotalVotes
FROM pictures a
LEFT JOIN votes b
ON a.id = b.pic_id
GROUP BY a.id, a.name, a.views
Use left join with a group function ,normal join keyword means an inner join and you need a left join for one to many relation
SELECT `pictures`.`id`,`pictures`.`views`, COUNT(`votes`.`pic_id`) as votes
FROM `pictures`
LEFT JOIN `votes`
ON `pictures`.`id` = `votes`.`pic_id`
GROUP BY `pictures`.`id`
Try this:
SELECT `pictures`.`id`,`pictures`.`views`, COUNT(`votes`.`pic_id`) as votes
FROM `pictures`
JOIN `votes`
ON `pictures`.`id` = `votes`.`pic_id`
GROUP BY `votes`.`pic_id`;
You need to try like this using the GROUP BY clause:
SELECT `pictures`.`id`,`pictures`.`views`, COUNT(`votes`.`pic_id`) as votes
FROM `pictures`
JOIN `votes`
ON `pictures`.`id` = `votes`.`pic_id`
group by `pictures`.`id`
I would like to get the data from one table, and count all results from other table, depending on the first table data, here is what I tried:
SELECT
cars.*, (
SELECT
COUNT(*)
FROM
uploads
WHERE
uploads.cid = cars.customer
) AS `count`,
FROM
`cars`
WHERE
customer = 11;
I dont really have an idea why its not working, as I'm not a regular MySQL user/coder...
Could anyone direct me in the right direction with this one?
SELECT
c.*, COUNT(u.cid) AS count
FROM
cars c
LEFT JOIN
uploads u
ON
u.cid=c.customer
WHERE
u.customer = 11;
GROUP BY c.cid
Try it by joining both tables using LEFT JOIN
SELECT a.customer, COUNT(b.cid) totalCount
FROM cars a
LEFT JOIN uploads b
ON a.customer = b.cid
WHERE a.customer = 11
GROUP BY a.customer
using COUNT(*) in LEFT JOIN will have records to have a minimum count of 1.
SELECT cars.*,COUNT(uploads.*) as uplloaded
from cars
left outer join uploads on uploads.cid = cars.customer
where cars.customer = 11
group by uploads.cid;
Try this :
SELECT customer, COUNT(cid) totalCount
FROM cars
INNER JOIN uploads
ON (customer = cid)
WHERE customer = 11
GROUP BY customer