Left join order by - mysql

I have property pictures in table with their sort_order starting from 0 to number of pictures.
What I would like to do is select pictures but I would like it to start from 2.
My approach was:
SELECT * FROM property_photos AS pp1
JOIN property_photos AS pp2 ON pp1.p_id = pp2.p_id
where pp2.sort_order =2
and pp2.sort_order <2
and pp1.sort_order >2
and pp1.p_id = 3
So what I am trying to gain here is the sort order would be like 2,0,1,3,4,5,6,7
so I need a self join but my query doesn't work

you don't need a join on this,
SELECT *
FROM property_photos
WHERE p_id = 3
ORDER BY (sort_order = 2) DESC, sort_order

Related

Searching and Sorting Using MySQL Inner Join

I guess I can't explain my problem properly. I want to explain this to you with a picture.
Picture 1
In the first picture you can see the hashtags in the trend section. These hashtags are searched for the highest total and it is checked whether the date has passed. If valid data is available, the first 5 hashtags are taken.
Picture 2
In the second picture, it is checked whether the posts in the hashtag are in the post, if any, the oldest date value is taken, LIMIT is set to 1 and the id value from the oyuncular table is matched with sid. Thus, the name of the person sharing can be accessed.
Picture 3
My English is a little bad, I hope I could explain it properly.
SELECT
social_trend.hashtag,
social_trend.total,
social_trend.tarih,
social_post.sid,
social_post.tarih,
social_post.post,
oyuncular.id,
oyuncular.isim
FROM
social_trend
INNER JOIN
social_post
ON
social_post.post LIKE '%social_trend.hashtag%' ORDER BY social_post.tarih LIMIT 1
INNER JOIN
oyuncular
ON
oyuncular.id = social_post.sid
WHERE
social_trend.tarih > UNIX_TIMESTAMP() ORDER BY social_trend.total DESC LIMIT 5
YOu should use a sibquery
and add a proper join between subqiery and social_trend
(i assumed sing both sid)
SELECT
social_trend.hashtag,
social_trend.total,
social_trend.tarih,
t.sid,
t.tarih,
t.post,
oyuncular.id,
oyuncular.isim
FROM (
select social_post.*
from social_post
INNER JOIN social_trend ON social_post.post LIKE concat('%',social_trend.hashtag,'%' )
ORDER BY social_post.tarih LIMIT 1
) t
INNER JOIN social_trend ON social_trend.hashtag= t.post
INNER JOIN oyuncular ON oyuncular.id = t.sid
WHERE
social_trend.tarih > UNIX_TIMESTAMP() ORDER BY social_trend.total DESC LIMIT 5
but looking to your new explanation and img seems you need
SELECT
t.hashtag,
t.total,
t.tarih_trend,
t.sid,
t.tarih,
t.post,
oyuncular.id,
oyuncular.isim
FROM (
select social_post.sid
, social_post.tarih
, social_post.post
, st.hashtag
, st.total
, st.tarih tarih_trend
from social_post
INNER JOIN (
select * from social_trend
WHERE social_trend.tarih > UNIX_TIMESTAMP()
order by total DESC LIMIT 5
) st ON social_post.post LIKE concat('%',st.hashtag,'%' )
ORDER BY social_post.tarih LIMIT 5
) t
INNER JOIN oyuncular ON oyuncular.id = t.sid

SQL query that limits the results to one when using count inside count

I am trying to select the count of likes on a specific project. The idea i came up with is
CAST(count(uploads.ID in (SELECT uploadID from votes)) as decimal) as numberoflikes
this works but the query then only returns one thing.
Entire query
SELECT DISTINCT users.NAME AS username
,users.ID AS userID
,subjects.NAME AS subjectname
,uploads.TIME
,uploads.description
,uploads.NAME
,uploads.ID
,CASE
WHEN uploads.ID IN (
SELECT uploadID
FROM votes
WHERE userID = 2
)
THEN CAST(1 AS DECIMAL)
ELSE CAST(0 AS DECIMAL)
END AS liked
,CASE
WHEN uploads.ID IN (
SELECT uploadID
FROM bookmarks
WHERE userID = 2
)
THEN CAST(1 AS DECIMAL)
ELSE CAST(0 AS DECIMAL)
END AS bookmarked
,CAST(count(uploads.ID IN (
SELECT uploadID
FROM votes
)) AS DECIMAL) AS numberoflikes
FROM uploads
INNER JOIN subjects ON (subjects.ID = uploads.subjectID)
INNER JOIN users ON (users.ID = uploads.userID)
INNER JOIN uploadGrades ON (uploads.ID = uploadGrades.uploadID)
INNER JOIN grades ON (grades.ID = uploadGrades.gradeID)
WHERE uploads.active = 1
AND subjects.ID IN (
SELECT subjectID
FROM userSubjects
INNER JOIN users ON (users.ID = userSubjects.userID)
WHERE userSubjects.userID = 2
)
AND grades.ID IN (
SELECT userGrades.gradeID
FROM uploadGrades
INNER JOIN userGrades ON (uploadGrades.gradeID = userGrades.gradeID)
WHERE userGrades.userID = 2
)
ORDER BY uploads.trueRating DESC;
Lets try a reduce version of your query, That is the base to get better answers
I reduce the initial query to user and upload to start. Also remove the fields you already know how to calculate.
.
SELECT DISTINCT users.NAME AS username
,users.ID AS userID
,uploads.NAME
,uploads.ID
,CAST(count(uploads.ID IN (
SELECT uploadID
FROM votes
)) AS DECIMAL) AS numberoflikes
FROM uploads
INNER JOIN users ON (users.ID = uploads.userID)
WHERE uploads.active = 1
ORDER BY uploads.trueRating DESC;
Then add votes with LEFT JOIN to replace the SELECT in the COUNT that way if not match you will get NULL and as I say in my comment COUNT doesnt count NULL's
.
SELECT DISTINCT users.NAME AS username
,users.ID AS userID
,uploads.NAME
,uploads.ID
,CAST(count(votes.uploadID)) AS DECIMAL) AS numberoflikes
FROM uploads
INNER JOIN users ON (users.ID = uploads.userID)
LEFT JOIN votes ON (uploads.ID = votes.uploadID)
WHERE uploads.active = 1
ORDER BY uploads.trueRating DESC;
Try something like this...
SELECT users.name as username, users.ID as userID, subjects.name as subjectname,
uploads.time, uploads.description, uploads.name, uploads.ID,
count(userVotes.userId), count(bookmarksMade.userId),
FROM uploads
join subjects on(subjects.ID = uploads.subjectID)
join users on(users.ID = uploads.userID)
join uploadGrades on(uploads.ID = uploadGrades.uploadID)
join grades on(grades.ID = uploadGrades.gradeID)
left join (select userId, uploadId from votes where userId = 2) as userVotes on uploads.id = userVotes.uploadId
left join (select userId, uploadId from bookmarks where userId = 2) as bookmarksMade on uploads.id = bookmarksMade.uploadId
join userSubjects on subjects.id = userSubjects.subjectID
WHERE uploads.active = 1 AND
userSubjects.userID = 2
ORDER BY uploads.trueRating DESC;
But, I am leaving out the userGrades thing, because you are doing a funky join there that I don't really understand (joining two tables on something that looks like it is not the whole primary key on either table).
Anyway, you really need to go to something more like this or what Oropeza suggests in his answer. Get more direct about what you want. This query looks like a monster that has been growing and getting things added in with "IN" clauses, as you needed them. Time to go back to the drawing board and think about what you want and how to get at it directly.
count(uploads.ID in (SELECT uploadID from votes)) as numberoflikes
group by uploads.Id ORDER BY uploads.trueRating DESC
I managed to do it like this. If i added the group by then it split the numberoflikes into rows and returned more then one row. Thanks for the help!

MySQL group by twice and COUNT

Some sql query gives me the following result:
As you can see, it already has GROUP BY.
So what I need? I need to group it again (by treatment_name) and count rows for each group. See more details on screenshot.
Here is full query:
SELECT
treatment_summaries.*
FROM `treatment_summaries`
INNER JOIN
`treatments`
ON
`treatments`.`treatment_summary_id` = `treatment_summaries`.`id`
AND
(treatment <> '' and treatment is not null)
INNER JOIN
`treatment_reviews`
ON
`treatment_reviews`.`treatment_id` = `treatments`.`id`
INNER JOIN
`conditions_treatment_reviews`
ON
`conditions_treatment_reviews`.`treatment_review_id` = `treatment_reviews`.`id`
INNER JOIN
`conditions` ON `conditions`.`id` = `conditions_treatment_reviews`.`condition_id`
INNER JOIN `conditions_treatment_summaries` `conditions_treatment_summaries_join`
ON
`conditions_treatment_summaries_join`.`treatment_summary_id` = `treatment_summaries`.`id`
INNER JOIN `conditions` `conditions_treatment_summaries`
ON `conditions_treatment_summaries`.`id` = `conditions_treatment_summaries_join`.`condition_id`
WHERE
`conditions`.`id` = 9
AND `conditions`.`id` IN (9)
AND (latest_review_id is not null)
GROUP BY
treatment_reviews.id
ORDER BY
treatment_summaries.reviews_count desc
LIMIT 20 OFFSET 0
Maybe there is another issue, cause GROUP BY should not leave same lines (for given column), but anyway you can wrap it like this:
SELECT * FROM ( YOUR_SQL_SELECT_WITH_EVERYTHING ) GROUP BY id
So the result you get will behave as another table and you can do all operations like GROUP BY again.

How to expand MySQL subquery/join to include all rows

This query below is perfect in producing the result for horse_id = 1 ... but I want to do this for all horses in the database. Can anyone share with me how to tweak this query so I can do that?
SELECT figures.entry_id,
max(figures.beyer)
FROM
( SELECT hrdb_lines.horse_id,
hrdb_entries.entry_id,
hrdb_lines.beyer
FROM hrdb_entries
INNER JOIN hrdb_lines
ON hrdb_lines.horse_id = hrdb_entries.horse_id
WHERE hrdb_lines.horse_id = 1
ORDER BY hrdb_lines.line_date DESC
LIMIT 2
) as figures
Perhaps I'm doing it all wrong too.
I think the following would generate the desired results:
SELECT `entry_id`, `beyer`
FROM (SELECT hrdb_entries.entry_id,
MAX( hrdb_lines.beyer )
FROM hrdb_entries
INNER JOIN hrdb_lines
ON hrdb_lines.horse_id = hrdb_entries.horse_id
GROUP BY hrdb_lines.horse_id
ORDER BY hrdb_lines.line_date DESC
) AS figures
If I'm understanding your question, something like this should be close:
SELECT
figures.horse_id,
figures.entry_id,
max(figures.beyer)
FROM
(SELECT
hrdb_lines.horse_id,
hrdb_entries.entry_id,
hrdb_lines.beyer
FROM hrdb_entries
INNER JOIN hrdb_lines ON hrdb_lines.horse_id = hrdb_entries.horse_id
ORDER BY hrdb_lines.line_date DESC
) as figures
GROUP BY figures.horse_id
One option to limit the MAX to just the most recent 2 beyer fields is to add a row number to the results and only include rows 1 and 2.
SELECT
figures.horse_id,
figures.entry_id,
max(figures.beyer)
FROM
(SELECT
#rn:=if(#prev_horse_id=horse_id,#rn+1,1) rn,
hrdb_lines.horse_id,
hrdb_entries.entry_id,
hrdb_lines.beyer,
#prev_horse_id:=hrdb_lines.horse_id
FROM hrdb_entries
INNER JOIN hrdb_lines ON hrdb_lines.horse_id = hrdb_entries.horse_id
INNER JOIN (SELECT #rn:=0) r
ORDER BY hrdb_lines.horse_id, hrdb_lines.line_date DESC
) as figures
WHERE rn <= 2
GROUP BY figures.horse_id

Select parents based on all children statisfying condition

This is such a simple problem but for some reason I cannot get my head round it today.
I have two entities:- title and product each respectively named tbl_title and tbl_product. Each title can have many products.
The product table has a field called unwanted which can be either null, 0 or 1.
I wish to select all titles based on where all products (ALL) have unwanted set to 1. So in other words I wish to select the parent based upon all children filling a certain condition. So if a title has one product that is unwanted but another that is not I do not wish for this title to enter the result set.
When I try this the most I get out of my head is:
SELECT * FROM `tbl_title`
left join tbl_product on tbl_product.title_id = tbl_title.id
where tbl_product.unwanted = 1
group by tbl_title.id
Which obviously does not work.
So how do I code such a query?
select * from tbl_title
where id not in (select title_id from tbl_product where unwanted = 0)
In English, this query eliminates all titles that have a wanted product.
From a style point of view, it would be better to call your column wanted, because unwanted = 0 is a double-negative of wanted = 1. It's always easier to get your head around positives.
SELECT t.id
FROM `tbl_title` t
left join tbl_product p on p.title_id = t.id
group by t.id
having sum(p.unwanted = 0 or p.unwanted is null) = 0
Try using a subquery like this:
SELECT * FROM `tbl_title` AS t
WHERE EXISTS (SELECT 1 FROM products WHERE title_id = t.id AND unwanted = 1)
AND NOT EXISTS (SELECT 1 FROM products WHERE title_id = t.id AND (unwanted = 0 OR unwanted IS NULL))
Just for the fields in title table
SELECT *
FROM `tbl_title` AS t
JOIN tbl_product AS v ON t.id = v.title_id
WHERE NOT EXISTS(
SELECT *
FROM tbl_product
WHERE (t.id = title_id)
AND (unwanted = 0 OR unwanted IS NULL)
GROUP BY t.id