I want to use a select query which gets data from tables.
It looks like this
SELECT table1.value1, table1.value2, table1.id, table2.id, table2.value2
FROM table1
INNER JOIN table2
ON table2.id = table1.value4
ORDER BY table1.id DESC
LIMIT 10
Though table1.value4 can sometimes be 0 and there are no table2.id with the value 0 and since it's a auto-increment value, it starts at 1. And I want it to start at 1.
Because when it's equal to 0 then that specific row isn't available, just the other ones.
But I would like to some how set a where clause that it only should get the table2 values if table1.value4 isn't equal to 0.
What you actually want, it seems, is a LEFT JOIN then. All rows from table1 will be returned, even if there is no match in table2 (as with table1.value4 = 0).
SELECT table1.value1, table1.value2, table1.id, table2.id, table2.value2
FROM
table1
LEFT JOIN table2
ON table2.id = table1.value4
ORDER BY table1.id DESC
LIMIT 10
TRy this::
If you dont have 0 in table2 id, the below query works fine::
SELECT table1.value1, table1.value2, table1.id, table2.id, table2.value2
FROM table1
INNER JOIN table2
ON table2.id = table1.value4
ORDER BY table1.id DESC
LIMIT 10
But there are some values in table2 having id 0 and you want that to be ignored then
SELECT table1.value1, table1.value2, table1.id, table2.id, table2.value2
FROM table1
INNER JOIN table2
ON (table2.id = table1.value4 and table1.id!=0)
ORDER BY table1.id DESC
LIMIT 10
Related
I searched around and found a near example to what I'm looking for, but it doesn't work in my case.
I have a query that does an INNER JOIN on two tables and this join constrains my overall data set substantially. I then want to LEFT JOIN onto a third table but I only want one record from that third table. The reason for the left join is because not every result of the INNER JOIN has a match in the 3rd table. Something like this:
SELECT DISTINCT t1.code, t2.id, t2.code, t3.id, t3.source_title, t3.display_order
FROM table1 t1
INNER JOIN table2 t2 ON t2.code=t1.code AND t2.type=0
LEFT JOIN table3 t3 ON t3.code=t1.code
ORDER BY t1.code, t3.display_order
This query returns too many records because the third table contains multiple records with a matching code. I just want the first one that matches with the lowest display_order value and, unfortunately, I can't limit the records to have display_order=1 because the lowest display order is not always one.
IMPORTANT: The t3.id value (if any) returned by this query must correspond to the record with the lowest display_order value. I.e., it won't work if the query correctly returns the lowest display_order value but the t3.id value corresponds to some other record in table 3.
Is this even possible? Any help would be much appreciated.
EDIT: Per Nick's suggestion, I have tried this, which appears to be working. I'll do some verification and report back:
SELECT DISTINCT t1.code, t2.*, sq.id, sq.source_title, sq.display_order
FROM table1 t1
INNER JOIN table2 p ON t2.code=t1.code AND t2.type=0
LEFT JOIN (
SELECT t3.*
FROM table3 t3
WHERE t3.display_order=(
SELECT MIN(display_order)
FROM table3 t3a
WHERE t3a.code = t3.code
)
) sq ON sq.code=t1.code
ORDER BY t1.code, sq.display_order
You should be able to replace table3 in your LEFT JOIN with
(SELECT *
FROM table3 t3
WHERE display_order = (SELECT MIN(display_order)
FROM table3 t3a
WHERE t3a.code = t3.code)
) t3
In MySQL 8.0 you can try to use row_number() for each code and ordered by display_order in a subquery from table3. Then left join that result and check for the row_number() to be equal to 1.
SELECT DISTINCT
t1.code,
t2.id,
t2.code,
t3.id,
t3.source_title,
t3.display_order
FROM table1 t1
INNER JOIN table2 t2
ON t2.code = t1.code
LEFT JOIN (SELECT t3.id,
t3.source_title,
t3.display_order,
t3.code,
row_number() OVER (PARTITION BY t3.code
ORDER BY t3.display_order) rn
FROM table3 t3) t3
ON t3.code = t1.code
WHERE t2.type = 0
AND t3.rn = 1
ORDER BY t1.code,
t3.display_order;
In lower versions you can try correlated subqueries ordered by display_order and LIMIT 1 (to get only one record).
SELECT DISTINCT
t1.code,
t2.id,
t2.code,
(SELECT t3.id
FROM table3 t3
WHERE t3.code = t1.code
ORDER BY t3.display_order,
t3.id
LIMIT 1) id,
(SELECT t3.source_title
FROM table3 t3
WHERE t3.code = t1.code
ORDER BY t3.display_order,
t3.id
LIMIT 1) source_title,
(SELECT t3.display_order
FROM table3 t3
WHERE t3.code = t1.code
ORDER BY t3.display_order,
t3.id
LIMIT 1) display_order
FROM table1 t1
INNER JOIN table2 t2
ON t2.code = t1.code
WHERE t2.type = 0
ORDER BY t1.code,
(SELECT t3.display_order
FROM table3 t3
WHERE t3.code = t1.code
ORDER BY t3.display_order,
t3.id
LIMIT 1);
I assumed, that display_order in table3 isn't unique but id is. So I added id to the ORDER BY clauses in the subqueries to make sure the same record is selected in each of them. If display_order is unique, you can remove id FROM the ORDER BY clauses.
Edit:
If you don't want to repeat the subqueries in the (overall) ORDER BY clause, you can also order by the column ordinals. E.g.:
...
ORDER BY 1, 6;
How do I go about doing an update with a join while using a limit
Error - Illegal use of limit operator
UPDATE
table1
INNER JOIN table2 ON table1.id = table2.id
SET
table1.field = 'your_value'
WHERE
table1.id = table2.id
LIMIT 1500
Possible solution, it's a bit of a hack
SET #tmp_c = 0;
UPDATE
table1
INNER JOIN table2 ON table1.id = table2.id
INNER JOIN table3 ON table2.id = table3.id
SET
table1.remove_date = NOW() - INTERVAL 5 MONTH
WHERE
table1.active = 1
AND
(IF (table1.active = 1, #tmp_c := #tmp_c + 1 , 0 )) //This is to only increment the counter if the whole where matches
AND
#tmp_c <= 15 //Start ignoring row items as soon as it exceeds the limit amount
;
if you want limit you should use a subselect and join this
UPDATE table1
INNER JOIN ( select * from table1
INNER JOIN table2 ON table1.id = table2.id
LIMIT 1500 ) t on t.id = table1.id
SET table1.field = 'your_value'
I have this SQL query and I am getting an error.
SELECT
table1.id as id,
CONCAT( table2.first_name , ' ' , table2.last_name ) as name,
table2.country_code as country_code,
(select table3.id from table3 where table3.user_id = table1.id AND table3.description NOT LIKE '%SOMETEXTHERE%' LIMIT 1) as trans_id,
table4.important as important,
table1.status as status
FROM table1
LEFT JOIN table2 ON eid = table2.id
LEFT JOIN table4 ON table4.ewallet_transaction_id = trans_id
ORDER BY transaction_date desc;
The error is: Error Code: 1054. Unknown column 'trans_id' in 'on clause'
But the trans_id does exist.
Note: I also try other alias for 'trans_id' like 'transaction_id'
This might be an easy question but I just cant figure it out. Thanks for your help in advance.
Because your mix join syntax
To allow the join to be processed, group the first two tables explicitly with parentheses so that the operands for the ON clause are (t1,t2) and t3:
SELECT * FROM (t1, t2) JOIN t3 ON (t1.i1 = t3.i3);
Alternatively, avoid the use of the comma operator and use JOIN instead:
SELECT * FROM t1 JOIN t2 JOIN t3 ON (t1.i1 = t3.i3);
You have to use a JOIN FOR table3 too, this way
SELECT
table1.id as id,
CONCAT( table2.first_name , ' ' , table2.last_name ) as name,
table2.country_code as country_code,
table31.trans_id as trans_id,
table4.important as important,
table1.status as status
FROM table1
INNER JOIN (select id as trans_id, user_id from table3 where table3.description NOT LIKE '%SOMETEXTHERE%' GROUP BY 1) table31 ON table1.id=table31.user_id
LEFT JOIN table2 ON eid = table2.id
LEFT JOIN table4 ON table4.ewallet_transaction_id = table31.trans_id
ORDER BY transaction_date desc;
here us the query
SELECT *
FROM Table1
WHERE complete='Y'
AND shipped='Y'
AND active='Y'
AND create_dttm > '2013-10-10 08:28:41'
AND order_id IN
(SELECT DISTINCT t1.order_id
FROM Table2 t1
INNER JOIN table3 t2 ON t1.prod_id = t2.prod_id
WHERE t2.prod_sku LIKE '%D-600%'
AND t1.create_dttm > '2013-02-15 08:28:41')
You are using a sub-query in WHERE clause, that could be the main reason behind slow execution of your query. Try using JOINS instead of sub query.
SELECT t1.*
FROM Table1 t1
INNER JOIN Table2 t2 ON T1.order_id = T2.order_id
AND t2.create_dttm > '2013-02-15 08:28:41'
INNER JOIN table3 t3 ON t2.prod_id = t3.prod_id
AND t3.prod_sku LIKE '%D-600%'
WHERE complete='Y'
AND shipped='Y'
AND active='Y'
AND create_dttm > '2013-10-10 08:28:41'
And also check for indexes on your tables.
I have 3 tables.
table1
id, thing_id
table_index
id
table_index_info
table_index_id, table1_id
table_index_info contains a history of table_index. This history can refer to table1, possibly many times or 0 times.
I need to run a query that returns all rows in table1 with a specific thing_id.
It also needs to count how many rows in table_index that have at least 1 table_index_info linking to table1.
Here's my query:
SELECT table1.*,
(SELECT COUNT(i.id)
FROM table_index i
WHERE EXISTS (SELECT 0
FROM table_index_info h
WHERE h.table1_id = table1.id
AND h.table_index_id = i.id)
) AS indexCount
FROM table1
WHERE table1.thing_id= $thingId
Is this the best/correct way to do this?
I would use a JOIN instead of EXISTS in this case.
SELECT table1.*,
( SELECT COUNT(i.id)
FROM table_index i
INNER JOIN table_index_info h ON h.table_index_id = i.id
WHERE h.table1_id = table1.id
) AS indexCount
FROM table1
WHERE table1.thing_id = $thingId