Ordering of grouped rows in mysql - mysql

SELECT t1.item_id, t1.item, t1.created, t1.owner, t1.type, t1.fld, t2.tag
FROM items AS t1
INNER JOIN tagged AS t2 ON t1.item_id = t2.item_id
WHERE tag
IN ('how', 'jkas', 'bodor', 'zimp', 'ctuo', 'sjex', 'kek'
)
GROUP BY item_id
ORDER BY t1.created DESC
LIMIT 0 , 100
How to order items by how many matches they have with IN TAG? I went really deep in manual and I couldn't find the answer and I got lost in stuff I don't understand.

You can use COUNT and put the results in a subquery:
SELECT *
FROM (
SELECT t1.item_id, t1.item, t1.created, t1.owner,
t1.type, t1.fld, t2.tag, COUNT(DISTINCT t2.tag) tagCount
FROM items AS t1
INNER JOIN tagged AS t2 ON t1.item_id = t2.item_id
WHERE tag IN ('how', 'jkas', 'bodor', 'zimp', 'ctuo', 'sjex', 'kek')
GROUP BY item_id
) t
ORDER BY tagCount DESC, created DESC
LIMIT 0 , 100

Related

select all row except those specified in the subquery

I make a selection on request and it behaves correctly.
SELECT t1.id, MIN(t1.rate)
FROM offers AS t1
WHERE t1.stock > 0
GROUP BY t1.ean;
AS soon as I nest it in another query, then the difficulty arises that WHERE NOT IN expects one column, but I need to keep MIN for GROUP BY to be preserved.
Here is query:
SELECT t2.id, t2.name, t2.ean
FROM offers AS t2
WHERE t2.id NOT IN (SELECT t1.id, MIN(t1.rate)
FROM offers AS t1
WHERE t1.stock > 0
GROUP BY t1.ean);
So here is answer:
SELECT t1.id
FROM offers AS t1
WHERE t1.id NOT IN (
SELECT f.id
FROM (SELECT
ean,
Min(net_price) AS minprice,
stock
FROM offers
GROUP BY ean
)
AS x INNER JOIN offers
AS f ON f.ean = x.ean AND f.net_price = x.minprice);

Join 4 Tables to find total and sort by total

i have 3 tables
1) users
2) user_likes
3) user_pictures
4) user_pucture_likes
users(id, name)
user_likes(id, user_id, like)
user_pictures(id, user_id, filename)
user_picture_likes(id, user_picture_id, like)
what i am trying to do is to sort the user on the total like on user_like + user_picture_like
I am not good with joining more than 2 tables.
i got upto here
SELECT t2.user_id, sum(t1.total_likes) as image_likes from user_pictures as t2 JOIN (
SELECT sum(like_status) as total_likes, user_picture_id FROM `user_picture_likes` GROUP BY user_picture_id ORDER BY total_likes DESC
)as t1
ON t1.user_picture_id = t2.id GROUP BY t2.user_id ORDER BY image_likes DESC
and how do i proceed from here?
Try this
SELECT T1.Id AS UserID, SUM(T2.like), Tmp.filename AS Image, Tmp.Imageslikes
FROM users T1
LEFT JOIN user_likes T2 ON T1.Id = T2.user_id
LEFT JOIN (
SELECT T3.user_id, T3.filename, SUM(T4.likes) Imageslikes
FROM user_pictures LEFT JOIN user_picture_likes T4 ON T3.Id = T4.user_picture_id
GROUP BY T3.user_id, T3.filename
)Tmp ON T1.Id = Tmp.user_id

Select only one row while doing groupby in mysql

T have the following table:
mid pid price
1 100 10
1 200 10
1 300 10
1 400 10
2 500 20
2 600 30
2 700 20
3 800 40
3 900 50
I want to find the least priced pid for each mid.
for that I was querying this code.
SELECT t1.mid,t1.pid
FROM tableName t1
JOIN (
SELECT mid, min(price) as min_price
FROM tableName
GROUP BY mid
) as t2 on t1.mid = t2.mid and t1.price = t2.min_price;
Ideally it should give result, but in my case in each group there are multiple pid having same price. so it is printing all the result.
but I just want to limit 1 row for each mid.
Is there any way to do this?
I have a
sqlfiddle demo
select s.mid,s.pid,s.price
from
(
SELECT t1.mid,t1.pid,t1.price,
if (t1.mid <> #p, #rn:=1,#rn:=#rn+1) rn,
#p:=t1.mid p
FROM (select #rn:=0,#p:=0) rn,t t1
order by t1.mid,t1.price,t1.pid
) s where s.rn = 1
TRY THIS: http://www.sqlfiddle.com/#!2/e2244c/71
SELECT t1.mid, MIN(DISTINCT t1.pid) AS Expr1
FROM tableName as t1
INNER JOIN
tableName AS tableName_1 ON t1.mid = tableName_1.mid
GROUP BY t1.mid
ORDER BY MIN(DISTINCT t1.pid) DESC
Try this:
select t1.*
from tablename t1
inner join (select mid, min(pid) min_pid from
(select t1.mid,t1.pid
FROM tablename t1
inner join (select mid,
min(price) as min_price
FROM tablename
GROUP BY mid) t2 on t1.mid = t2.mid
and t1.price = t2.min_price) t
group by mid) t2 on t1.mid = t2.mid
and t1.pid = t2.min_pid
;
It produces rows with minimum price and minimum pid.
It's works:
SELECT t1.mid,t1.pid FROM tableName t1
INNER JOIN (
SELECT mid AS mid1, pid AS pid1, min(price) as min_price FROM tableName GROUP BY mid
) as t2
on t1.mid = t2.mid1 and t1.price = t2.min_price and t1.pid = t2.pid1;

Why do I receive an error at this join tables?

I wrote this:
SELECT DISTINCT CATEGORY FROM T AS T1
CROSS JOIN (SELECT *
FROM T
WHERE T.CATEGORY = T1.CATEGORY
ORDER BY CATEGORY DESC
LIMIT 10)
and I receive this
"Unknown column 'T1.CATEGORY' in 'where clause'".
Why?
Update:
My purpose of this is to get 10 posts of any category.
Because T1 is not visible from within the subquery.
Your JOIN also serves no purpose and/or you probably forgot the JOIN condition.
In JOIN condition should use ON keyword
SELECT DISTINCT CATEGORY FROM T AS T1
CROSS JOIN SELECT * FROM T ON T.CATEGORY = T1.CATEGORY
ORDER BY CATEGORY DESC LIMIT 10;
If you need to get 10 posts of each category you can use a query like this:
SELECT CATEGORY, Post
FROM (
SELECT a.CATEGORY, a.Post, count(*) as rn
FROM #T a
JOIN #T b ON a.CATEGORY = b.CATEGORY AND a.Post >= b.Post
GROUP BY a.CATEGORY, a.Post) dt
WHERE rn < 11;

MySQL reference outer table alias in subquery error

select c.*
from posts p
join comments c on (p.id=c.post_id)
and c.status = 'A'
and c.id >= (select MIN(id) from (select id from comments where post_id=p.id order by id DESC LIMIT 7) as c2)
where p.comments_count > 0 AND p.id IN (247,245,244,243,242,241)
In the above sql query I get this mysql error Unknown column 'p.id' in 'where clause' it seems like in the subquery p.id isn't able to get referenced. Is there anyway that I can get the posts table id referenced in this subquery?
I think you are trying to fetch latest 7 comments for each post. Could you try this? you can test here http://www.sqlfiddle.com/#!2/a222e/3/0
The First Attempt
I tried below SQL.
SELECT *
FROM comments t1
WHERE post_id IN (247,254,244,243,242,241)
AND id IN (
SELECT id
FROM comments
WHERE t1.id = id
LIMIT 7
);
But I got an error "This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery"
Another Approach
So, I tried self join on comments to generate sequence number.
SELECT id
FROM (
SELECT t1.id, COUNT(*) AS cnt
FROM comments t1 INNER JOIN comments t2
ON t1.post_id = t2.post_id
WHERE t1.id <= t2.id
AND t1.post_id IN (247,254,244,243,242,241)
AND t2.post_id IN (247,254,244,243,242,241)
GROUP BY t1.id
) x
WHERE cnt <= 7;
inner sub-query uses self join and produces cnt column which has sequential value for each comment id of post.
But preceding query only fetches id of comment
Finally to get all columns of comment table, following query should be executed.
SELECT *
FROM comments c INNER JOIN (
SELECT id
FROM (
SELECT t1.id, COUNT(*) AS cnt
FROM comments t1 INNER JOIN comments t2
ON t1.post_id = t2.post_id
WHERE t1.id <= t2.id
AND t1.post_id IN (247,254,244,243,242,241)
AND t2.post_id IN (247,254,244,243,242,241)
GROUP BY t1.id
) x
WHERE cnt <= 7
) t USING (id);
Using User Variables
Actually you have another chance using MySQL user variable. I didn't mention this interesting MySQL feature because I was not sure I understood your question correctly.
SELECT *
FROM (
SELECT post_id, id,
IF (#pid = post_id, #cnt := #cnt + 1, #cnt := 1) AS cnt,
#pid := post_id
FROM comments, (SELECT #pid := 0, #cnt := 0) tmp
WHERE post_id IN (247,254,244,243,242,241)
ORDER BY post_id, id DESC
) x
WHERE cnt <= 7;
Preceding SQL looks like simpler (means good performance) than older join version. but not tested on large data set.
You can only access the outer query 1 level deep. So try doing you where filter on the middle query:
SELECT MIN(id)
FROM (
SELECT id, post_id
FROM comments
ORDER BY id DESC
LIMIT 7
)
WHERE post_id = p.id