MySQL LIMIT inside IN Operator - mysql

select distinct column1
from Table1
where Table1id in ((select T2.Table1id
from Table2 T2
where (conditions)
order by T2.column)
limit 2
);
I cannot use limit inside the In operator. Do we have any other way to limit inside IN operator? Or do we have any other way without using IN and also without using any joins?
Error (while using limit inside the In Operator):-
Error Code: 1235. This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'

For non-specific MySQL versions, Ergest gave you a good solution of using JOIN. Here is another workaround in which an outer layer is used on top of the derived table.
select distinct column1
from Table1
where Table1id in (select id
from
(select T2.Table1id as id
from Table2 T2
where (conditions)
order by T2.column
limit 2) tb);
PS: this trick can be used to bypass the ERROR 1093 (HY000): You can't specify target table 'terms' for update in FROM clause

What a weird restriction. Well, you can simply use an ad-hoc view (aka. WITH clause or CTE):
with limited as
(
select T2.Table1id
from Table2 T2
where (conditions)
order by T2.column
limit 2
)
select distinct column1
from Table1
where Table1id in (select Table1id from limited);
Demo: https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=cc148fae3a1089324446ec792e1476e2

Let's turn it inside out:
select distinct T1.column1
FROM
( SELECT T2.Table1id
from Table2 T2
where (conditions)
order by T2.column
limit 2
) AS x
JOIN Table1 AS T1 ON T1.table1id = x.Table1id
The inner (derived) table may need DISTINCT.

Related

Mysql select from two tables where first table field = second table field%

I have two tables.
table1 has a row id='12345'
table2 has a row where the id = that of table1 with added chars, e.g.,
table2.id = '12345-678qt'
table2 may have more than one id starting with '12345-' with different ending chars.
Yes, there is always a dash after table1's id that could be used in the query.
I need to get some data from both tables, say
SELECT table1.id, table1.field9,
table2.id, table2.fieldZ
FROM table1 and table2
WHERE (
table1.id=table2.id's characters before the dash
OR
table1.field1 = 'abcde'
)
AND table2.dataB='something'
ORDER BY table1.datefield DESC LIMIT 3;
Thank you.
The MySQL translation of:
"table1 and table2 WHERE" is table1 INNER JOIN table 2 ON
"table2.id's characters before the dash" is SUBSTRING_INDEX(table2.id, '-', 1)
The query should look like this:
SELECT table1.id, table1.field9,
table2.id, table2.fieldZ
FROM table1
INNER JOIN table2
ON (table1.id = SUBSTRING(table2.id, '-', 1) OR table1.field1 = 'abcde')
AND table2.dataB = 'something'
ORDER BY table1.datefield DESC
LIMIT 3;
This doesn't grant that your query will work if it's written like this. My fixes will remove the current errors inside your query. For more troubleshooting with a sql fiddle link, please provide tables and I'll be happy to help.
Check the official documentation about the JOIN operation and the SUBSTRING_INDEX function at the corresponding links.

Can I use 1 instead of asterisk for SQL_CALC_FOUND_ROWS?

Here is my query:
SELECT t1.mycol
FROM mytable t1
JOIN mytable t2
ON t1.id = t2.postid
ORDER BY value
LIMIT 10;
It works well.
Now I need to count the number of matched rows without the limitation. So I have've added this SQL_CALC_FOUND_ROWS * to the select statement and my query throws:
value is ambiguous in the order by clause.
Why? And how can I fix it?
Noted that, when I use SQL_CALC_FOUND_ROWS 1 instead of SQL_CALC_FOUND_ROWS * in the select statement, then apperantly all fine. So, is it ok to use SQL_CALC_FOUND_ROWS 1? (I'm asking this because that's SQL_CALC_FOUND_ROWS * in the documentation).
I'm not sure why you are using a self-join, but you say the query does what you want.
Your problem is simply the lack of a qualified column name in the order by. It has nothing to do with SQL_CALC_FOUND_ROWS:
SELECT SQL_CALC_FOUND_ROWS t1.mycol
FROM mytable t1 JOIN
mytable t2
ON t1.id = t2.postid
ORDER BY t1.value
LIMIT 10;
I do not know why your original query would have worked. It has the same ambiguous column name in the ORDER BY.
Give it a try:
SELECT SQL_CALC_FOUND_ROWS * from mytable t1
JOIN mytable t2
ON t1.id = t2.postid
ORDER BY t1.value
LIMIT 10;
SELECT FOUND_ROWS();
The reason why you got the error was that, you are joining table with itself, so obviously, every column would occur twice. That's why the name is ambiguous. I added quelifier t1.
Try this
SELECT SQL_CALC_FOUND_ROWS t1.* from mytable t1
JOIN mytable t2
ON t1.id = t2.postid
ORDER BY t1.value
LIMIT 10;
SELECT FOUND_ROWS();

SELECT FROM view1, view2 when data available (JOIN?)

I'm not a SQL guy, and I've just tried every JOIN MySQL offers.
I primarily need data from view1 using WHERE, ORDER BY, LIMIT with offset (the data is incorrect without those conditions.)
view1 is not limited by view2
Data also needs to be pulled from view2, but view2 has its' own WHERE (or whatever's best) condition
view2 may not have corresponding data, but it shouldn't be grabbed without being linked to view1 (NULLs are just fine!)
I'll just give you the two SELECTs that work for me rather than the hashes I've come up with.
For view1:
SELECT * FROM view1
WHERE column1 IS NULL OR column1 = 1
ORDER BY dateColumn DESC LIMIT index1, count1;
(index1 and count1 are INs i use for a stored proc)
For view2:
SELECT * FROM table2
WHERE column1 = ? AND table1_id IN (
SELECT id FROM view1
WHERE column1 IS NULL OR column1 = 1
ORDER BY dateColumn DESC LIMIT index1, count1
)
GROUP BY table1_id
(? is any arbitrary value i put in)
I'm at wits end. I have no idea how to fuse these two.
Specifics
Please note that the IN for view2 is almost identical to the view1 query. Thanks!
You can write a subquery for table2 and add WHERE clause there, also you can add WHERE clause at the ent of the query -
SELECT * FROM table2 t2
JOIN (
SELECT id FROM table1
WHERE column1 IS NULL OR column1 = 1
ORDER BY dateColumn DESC
LIMIT index1, count1
) t1
ON t1.id = t2.table1_id
WHERE
t2.column1 = ?
GROUP BY
t2.table1_id
In this example I used JOIN instead of WHERE IN condition.
How about this query:
Select t1.id
FROM table1 t1
JOIN table2 t2 ON t1.id = t2.table1_id
WHERE t1.column1 IS NULL OR t1.column1 = 1
i think it should help you
Select TableName1.id
FROM TableName1
JOIN TableName2 ON TableName1.id = TableName2.id
WHERE TableName1.column1 IS NULL OR TableName1.column1 = 1

MySQL if join table.col exists case as part of the query itself?

I have a weird situation here that I try to resolve through SQL so I don't have to modify much in the application :).
Is there ANY way that I can tell if a column exists in a quere within the query?
(Table2 is not always joined in the query)
SELECT * FROM
Table1 as T1
join Table2 as T2 on t1.id = t2.fk
WHERE
T1.something > 10 OR (IF(table and column exists in the query T2.col, 1, 0);
my alternative is to always join Table2 (painful in this case).
Any SQL guru/genius can help?
I solved the problem with an easy work around. So, for the sake of referencing...
SELECT *
FROM Table1 as T1
WHERE T1.something > 10 OR ((SELECT ....) = 1)

mysql subquery field application Range

Here is my code:
SELECT field1, field2,
(SELECT * FROM table1 WHERE a = field2),
(SELECT COUNT(*)
FROM (SELECT *
FROM table2
WHERE c = field2) as t1) as count
FROM table3;
...and here is error message:
/* SQL Error (1054): Unknown column
'field2' in 'where clause' */
I want to execute one query, to get table2's total counts.
The problem is that you're trying to use a variable declared in the outer query in the inner query. Variables are scoped the opposite way in SQL, you only have access to inner queries. What you want to do (I believe) is look for the number of table2 that have a c that matches the a from table1. This should give you that answer.
SELECT
table1.a,
table2.c,
count(*)
FROM
table1
JOIN
table2 ON table2.c = table1.a
GROUP BY
table1.a
I re-wrote your query as:
SELECT t3.field1,
t3.field2,
t1.*,
t2.cnt
FROM TABLE3 t3
LEFT JOIN TABLE1 t1 ON t1.a = t3.field2
LEFT JOIN (SELECT t.c,
COUNT(*) AS cnt
FROM TABLE2 t
GROUP BY t.c) t2 ON t2.c = t3.field2
The 1054 error is due to referencing field2 two subqueries deep - most only support one level deep.
UPDATE:
I want to edit the answer, since in MySQL 8.0 your query is already correct, derived tables can access external references no matter the level.
SELECT field1, field2,
(SELECT 'hola' FROM table1 WHERE a = field2),
(SELECT COUNT(*)
FROM (SELECT *
FROM table2
WHERE c = field2) as t1) as count
FROM table3;
"Prior to MySQL 8.0.14, a derived table cannot contain outer references. This is a MySQL restriction that is lifted in MySQL 8.0.14, not a restriction of the SQL standard. For example, the derived table dt in the following query contains a reference t1.b to the table t1 in the outer query:" https://dev.mysql.com/doc/refman/8.0/en/derived-tables.html