Unique result set with inner join query - mysql

SELECT
*
FROM `catalog_webdesign_products` t
INNER JOIN tbl_member_registration t1 ont.userid=t1.fld_loginid
WHERE 1
AND t1.fld_member_category_level<9
AND t.product_img IS NOT NULL
ORDER BY RAND() LIMIT 5
In this query , I need rows with unique userid. I had tried 'group by userid' also but then product_img with null value is coming in result set.

yes you can use GROUP BY userid. but your query looks wrong here
INNER JOIN tbl_member_registration t1 on t.userid=t1.fld_loginid
^------------------------space here
try this
SELECT
*
FROM `catalog_webdesign_products` t
INNER JOIN tbl_member_registration t1 on t.userid=t1.fld_loginid
WHERE t1.fld_member_category_level<9
AND t.product_img IS NOT NULL
group by userid
ORDER BY RAND() LIMIT 5
edit:
SELECT
*
FROM (select * from `catalog_webdesign_products` where product_img IS NOT NULL) t
INNER JOIN tbl_member_registration t1 on t.userid=t1.fld_loginid
WHERE t1.fld_member_category_level<9
group by t.userid
ORDER BY RAND() LIMIT 5

For better performance you should move the condition for t1 into join statement. You problem could be the wrong JOIN condition. Try LEFT JOIN instead of INNER JOIN.
More about joins: http://www.w3schools.com/sql/sql_join.asp
SELECT *
FROM `catalog_webdesign_products` t
LEFT JOIN tbl_member_registration t1
ON (t.userid = t1.fld_loginid AND t1.fld_member_category_level < 9)
WHERE t.product_img IS NOT NULL
GROUP BY t.userid
ORDER BY RAND() LIMIT 5

Related

How to ORDER BY a temporary table

In the following query I want to ORDER BY RAND() c table. When I put the ORDER BY RAND() inside the JOIN, query need more than 5 seconds to execute because ORDER BY runs before GROUP BY.
UPDATE `backlinks` as a
JOIN (
SELECT b.`id` as bid
FROM `backlinks` b
WHERE b.`googlebot_id` IS NULL
AND b.`used_time` IS NULL
AND b.`campaign_id` IN (
SELECT `id` FROM `campaigns` WHERE `status`=true
)
GROUP BY b.`campaign_id`
) AS c ON a.id = c.bid
SET a.`crawler_id` = 'test'
limit 1;
Why you are using group by withou ana aggregation function
if you want just a row for each b.campaign_id use some aggregation function for avoid unpredictable result for others column value and error with the most recente version of db
a proper aggregation function could avoid the needs for order by and limit 1
and for performance you could avoid the IN clause for a subquery and use inner join this produce the same result but is more fast
UPDATE `backlinks` as a
JOIN(
SELECT min(b.`id`) as bid
FROM `backlinks` b
INNER JOIN (
SELECT `id`
FROM `campaigns`
WHERE `status`=true
) t1 on t1.id = b.`campaign_id`
WHERE b.`googlebot_id` IS NULL
AND b.`used_time` IS NULL
GROUP BY b.`campaign_id`
) AS c ON a.id = c.bid
SET a.`crawler_id` = 'test'
limit 1;
Anyway if you are using mysql version prevoius then 5.7 you can use group by without aggreation function .. and order by .. but .. both of that have an impact on performance
UPDATE `backlinks` as a
JOIN(
SELECT b.`id` as bid
FROM `backlinks` b
INNER JOIN (
SELECT `id`
FROM `campaigns`
WHERE `status`=true
) t1 on t1.id = b.`campaign_id`
WHERE b.`googlebot_id` IS NULL
AND b.`used_time` IS NULL
GROUP BY b.`campaign_id`
) AS c ON a.id = c.bid
SET a.`crawler_id` = 'test'
limit 1;
the uniques way for improve performance is related to the use of join instead of IN clause and a proper index on table backlinks columns campaign_id
you could try using order by rand and limit outside the subquery but inside a proper outer subquery and join the result for the update
UPDATE `backlinks` as a
INNER JOIN (
select a1.id
from backlinks as a1
INNER JOIN (
SELECT b.`id` as bid
FROM `backlinks` b
INNER JOIN (
SELECT `id`
FROM `campaigns`
WHERE `status`=true
) t1 on t1.id = b.`campaign_id`
WHERE b.`googlebot_id` IS NULL
AND b.`used_time` IS NULL
GROUP BY b.`campaign_id`
) AS c ON a1.id = c.bid
ORDER BY rand()
limit 1
) t on t.id = a.id

how to use 'inner join' and 'order by' in sql

I want to use inner join and order in my query in php page.
My query :
select
*
from
table1
inner join
table1category
on table1.table1category_id = table1category.id
order by updateDate desc;
'updateDate' is for table1 => error : Column 'updateDate' in order clause is ambiguous
Column 'updateDate' in order clause is ambiguous
Means that updateDate exists in both tables you are trying to use.
If you want to order using this field, you have to specify from which table you want it to be ordered by.
For example:
SELECT
*
FROM table1
INNER JOIN table1category
ON table1.table1category_id = table1category.id
ORDER BY table1.updateDate DESC;
Also, consider that using * on a SELECT with JOINS will get all the columns from all the included tables.
when there is same column in two table then you've to specify the table name with that columns
SELECT
*
FROM table1
INNER JOIN table1category
ON table1.table1category_id = table1category.id
ORDER BY table1.updateDate DESC;
Its because updateDate exists in both tables- table1 and table1category
SELECT
*
FROM table1 t
INNER JOIN table1category tc
ON t.table1category_id = tc.id
ORDER BY t.updateDate DESC;
You have to say which table to use for this field (presents in both tables):
select *
from table1
inner join table1category on table1.table1category_id = table1category.id
order by XXX.updateDate desc;
Replace XXX by table1 or table1category.
You can set aliases on tables too, like:
select *
from table1 as myalias1
inner join table1category as myalias2 on table1.table1category_id = table1category.id
order by XXX.updateDate desc;
Then replace XXX by myalias1 or 2.
You can do the same for selecting datas (for example):
SELECT table1.id AS id, table2.id AS categoryId
Column updateDate in order clause is ambiguous
Try This
SELECT
*
FROM table1 t1
INNER JOIN table1category t2
ON t1.table1category_id = t2.id
ORDER BY t1.updateDate DESC;
I find that using aliases often makes joins easier
SELECT
*
FROM table1 AS alias1
INNER JOIN table1category AS alias2
ON alias1.table1category_id = alias2.id
ORDER BY alias1.updateDate DESC;
You are missing table name
SELECT
*
FROM table1
INNER JOIN table1category
ON table1.table1category_id = table1category.id
ORDER BY table1.updateDate DESC;
SELECT *, table1.updateDate as "Table1 Update Date"
FROM table1
INNER JOIN table1category ON table1.table1category_id = table1category.id
ORDER BY table1.updateDate DESC;
or you can keep alias in ORDER BY clause
SELECT *, table1.updateDate as "Table1 Update Date"
FROM table1
INNER JOIN table1category ON table1.table1category_id = table1category.id
ORDER BY "Table1 Update Date" DESC;
Note
Use keywords always in UPPER case
Better to use alias in SELECT CLAUSE for better understanding, otherwise it will add 1 to updateDate i.e. updateDate1.
Always use alias for same column names
Don't use all columns i.e. * , fetch only required columns
select
*
from
table1 T
inner join
table1category C
on T.table1category_id = C.id
order by T.updateDate desc;

How to remove duplicates from table using join in mysql

select *
from
(
SELECT id, imei1, status
FROM `owarranty_imei` mto
WHERE EXISTS
(
SELECT 1
FROM `owarranty_imei` mti
WHERE mto.imei1=mti.imei1
LIMIT 1, 1
)
) t1
left join `owarranty_warranty_activations` as t2 on t1.id=t2.imei_id
where t2.id is null
limit 100
this is my query. In owarranty_imei has more than 100000 records. i want to get duplicates from imei table which owarranty_imei not in owarranty_warranty_activation table. This query work for few records but when i run it for more than 1000000 records its not working
SELECT
mto.id,
mto.imei1,
mto.status
FROM
`owarranty_imei` mto
INNER JOIN
`owarranty_imei` mti ON mto.imei1=mti.imei1
LEFT JOIN
`owarranty_warranty_activations` as t2 ON mto.id=t2.imei_id
GROUP BY mto.id
HAVING COUNT(t2.id)=0

Rewrite 2 select statements as one JOIN Statement

I've been strugling with a JOIN statement which I can't figure out.
I want to get the latest(newest) entry in two different tables and join the result in the output.
The 2 Select statements look like this and they work as expected but I can't seem to get the right result when I try to rewite them as a JOIN statement.
Please help, Thanks.
SELECT MaxNum
FROM table1
WHERE UserID = 4
ORDER BY Date DESC
LIMIT 1
SELECT MinNum
FROM table2
WHERE UserID = 4
ORDER BY Date DESC
LIMIT 1
I'm not sure that a join necessarily makes sense here. However, you can slightly modify what you currently have to be one query:
SELECT
(SELECT MaxNum FROM table1 WHERE UserID = 4 ORDER BY Date DESC LIMIT 1) AS MaxNum,
(SELECT MinNum FROM table2 WHERE UserID = 4 ORDER BY Date DESC LIMIT 1) AS MinNum
Since each of these queries only returns one row, one dirty trick you can use is to cross join the results:
SELECT MaxNum, MinNum
FROM (SELECT MaxNum
FROM table1
WHERE UserID = 4
ORDER BY Date DESC
LIMIT 1) t
CROSS JOIN (SELECT MinNum
FROM table2
WHERE UserID = 4
ORDER BY Date DESC
LIMIT 1) s
select TOP 1 table1.MaxNum, table2.MinNum
FROM table1 INNER JOIN table2
ON table1.UserID = table2.UserID
WHERE table1.UserID = 4
ORDER BY table1.Date DESC
If you want to display result as one row then use your queries as subqueries in FROM clause.
SELECT *
FROM
(SELECT MaxNum FROM table1 WHERE UserID = 4 ORDER BY `Date` DESC LIMIT 1) AS q1,
(SELECT MinNum FROM table2 WHERE UserID = 4 ORDER BY `Date` DESC LIMIT 1) AS q2;

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;