My Question is
Which Clause use instead of IN Clause in MYSQL with PHP
Because IN Clause Limit 1024 character.
My Character limit exceed to 1024 character.
SELECT * FROM TblUser
WHERE Status != 'Deleted' AND UserId IN (0,10,11,12,13,14,15,22,45,114,144,155,156,167,211,439,440,441,443,445,450,455,456,457,458,459,1111,1154,1156,1165,1451,1541,11111,11112,11113,11114,11115,11116,11117,11118,11119,11656,15451,16561,17671,18781,33131,33311,33411,54511,111110,111111,111112,111113,111114,111115,111116,111117,111118,111119,111120,111121,111122,111123,111124,111125,111126,111127,111128,111129,111130,111131,111132,111133,111134,111135,111136,111137,111138,111139,111140,111141,111142,111143,111144,111145,111146,111147,111148,111149,111150,111151,111152,111153,111154,111155,111156,111157,111158,111159,111160,111161,111162,111163,111164,111165,111166,111167,111168,111169,111170,111171,111172,111173,111174,111175,111176,111177,111178,111179,111180,111181,111182,111183,111184,111185,111186,111187,111188,111189,111190,111191,111192,111193,111194,111195,111196,111197,111198,111199,1111100,11112101,11112102,11112103,11112104,11112105,11112106,11112107,11112108,11112109,11112110,11112111,11112112,11112113,11112114,11112115,11112116,11112117,11112118,11112119,11112120,11112121,11112122,11112123,11112124,11112125,11112126,11112127,11112128,11112129,11112130,11112131,11112132,11112133,11112134,11112135,11112136,11112137,11112138,11112139,11112140,11112141,11112142,11112143,11112144,11112145,11112146,11112147,11112148,11112149,11112150,11112151,11112152,11112153,11112154,11112155,11112156,11112157,11112158,11112159,11112160,11112161,11112162,11112163,11112164,11112165,11112166,11112167,11112168,11112169,11112170,11112171,11112172,11112173,11112174,11112175,11112176,11112177,11112178,11112179,11112180,11112181,11112182,11112183,11112184,11112185,11112186,11112187,11112188,11112189,11112190,11112191,11112192,11112193,11112194,11112195,11112196,11112197,11112198,11112199,11112200);
Please help Which Clause use instead of IN Clause in MYSQL with PHP?
Is the list of values that are used in the IN statement always the same, or is that list the result of some other query? If the latter is the case, you could use that query as a subquery:
SELECT * FROM tbluser
WHERE status != 'Deleted'
AND userid IN
( SELECT userid FROM sometable WHERE ... )
Yes you are limited within an IN statement, one thing you could do is create a temporary table which stores the values.
CREATE TEMPORARY TABLE IF NOT EXISTS temp AS (SELECT userid FROM tbluser);
In PHP create your INSERT INTO script:
$str = '0,10,11,12,13,14,15,22,45,114,144,155,156,167,211,439,440,441,443,445,450,455,456,457,458,459,1111,1154,1156,1165,1451,1541,11111,11112,11113,11114,11115,11116,11117,11118,11119,11656,15451,16561,17671,18781,33131,33311,33411,54511,111110,111111,111112,111113,111114,111115,111116,111117,111118,111119,111120,111121,111122,111123,111124,111125,111126,111127,111128,111129,111130,111131,111132,111133,111134,111135,111136,111137,111138,111139,111140,111141,111142,111143,111144,111145,111146,111147,111148,111149,111150,111151,111152,111153,111154,111155,111156,111157,111158,111159,111160,111161,111162,111163,111164,111165,111166,111167,111168,111169,111170,111171,111172,111173,111174,111175,111176,111177,111178,111179,111180,111181,111182,111183,111184,111185,111186,111187,111188,111189,111190,111191,111192,111193,111194,111195,111196,111197,111198,111199,1111100,11112101,11112102,11112103,11112104,11112105,11112106,11112107,11112108,11112109,11112110,11112111,11112112,11112113,11112114,11112115,11112116,11112117,11112118,11112119,11112120,11112121,11112122,11112123,11112124,11112125,11112126,11112127,11112128,11112129,11112130,11112131,11112132,11112133,11112134,11112135,11112136,11112137,11112138,11112139,11112140,11112141,11112142,11112143,11112144,11112145,11112146,11112147,11112148,11112149,11112150,11112151,11112152,11112153,11112154,11112155,11112156,11112157,11112158,11112159,11112160,11112161,11112162,11112163,11112164,11112165,11112166,11112167,11112168,11112169,11112170,11112171,11112172,11112173,11112174,11112175,11112176,11112177,11112178,11112179,11112180,11112181,11112182,11112183,11112184,11112185,11112186,11112187,11112188,11112189,11112190,11112191,11112192,11112193,11112194,11112195,11112196,11112197,11112198,11112199,11112200';
$ids = explode(',', $str);
foreach ($ids as $value){
echo 'INSERT INTO temp VALUES(' . $value . '); </br>';
}
But change the echo for the mysqli query.
Then:
SELECT * FROM tbluser u
where status !='Deleted'
And exists(select * from temp u1 where u1.userid = u.userid)
Or you can do an inner join temp u1 on u1.userid = u.userid
#Abid as you mentioned your question in this case #Guss is right.
What i am thinking if values mentioned IN clause comes from GROUP_CONCAT then might be possible duplicate values exist with comma seperated. So to remove duplicacy we can use DISTINCT.
For example :
SELECT GROUP_CONCAT(UserId) FROM sometable
Above query can give duplicate values.
SELECT GROUP_CONCAT(DISTINCT UserId) FROM sometable
SELECT t1.UserRoleId, t1.EntityId, GROUP_CONCAT( DISTINCT t1.PermissionId ) AS Permissions
FROM userpermission t1, bill_companies t2
WHERE t1.Status = 'Active'
AND t2.status = 'Active'
AND UserGroupId
IN ( 84, 85, 86 )
LIMIT 0 , 30
Above query gives you userid's without duplicacy. This can also reduce the size of comma seperated ids.
Hope this will help.
You could create groups using php if there are Ids which follow by increment e. g. 1,2,3 and replace them by a OR (id >= 1 AND id <= 3)
Alternative approach:
Search Max and Min ID in your List and query using an interval (greater than and less than) and use php to do the job.
If you really want to avoid using IN then you could use FIND_IN_SET():-
SELECT * FROM TblUser
WHERE Status != 'Deleted' AND FIND_IN_SET(UserId, '0,10,11,12,13,14,15,22,45,114,144,155,156,167,211,439,440,441,443,445,450,455,456,457,458,459,1111,1154,1156,1165,1451,1541,11111,11112,11113,11114,11115,11116,11117,11118,11119,11656,15451,16561,17671,18781,33131,33311,33411,54511,111110,111111,111112,111113,111114,111115,111116,111117,111118,111119,111120,111121,111122,111123,111124,111125,111126,111127,111128,111129,111130,111131,111132,111133,111134,111135,111136,111137,111138,111139,111140,111141,111142,111143,111144,111145,111146,111147,111148,111149,111150,111151,111152,111153,111154,111155,111156,111157,111158,111159,111160,111161,111162,111163,111164,111165,111166,111167,111168,111169,111170,111171,111172,111173,111174,111175,111176,111177,111178,111179,111180,111181,111182,111183,111184,111185,111186,111187,111188,111189,111190,111191,111192,111193,111194,111195,111196,111197,111198,111199,1111100,11112101,11112102,11112103,11112104,11112105,11112106,11112107,11112108,11112109,11112110,11112111,11112112,11112113,11112114,11112115,11112116,11112117,11112118,11112119,11112120,11112121,11112122,11112123,11112124,11112125,11112126,11112127,11112128,11112129,11112130,11112131,11112132,11112133,11112134,11112135,11112136,11112137,11112138,11112139,11112140,11112141,11112142,11112143,11112144,11112145,11112146,11112147,11112148,11112149,11112150,11112151,11112152,11112153,11112154,11112155,11112156,11112157,11112158,11112159,11112160,11112161,11112162,11112163,11112164,11112165,11112166,11112167,11112168,11112169,11112170,11112171,11112172,11112173,11112174,11112175,11112176,11112177,11112178,11112179,11112180,11112181,11112182,11112183,11112184,11112185,11112186,11112187,11112188,11112189,11112190,11112191,11112192,11112193,11112194,11112195,11112196,11112197,11112198,11112199,11112200')
However the only limit for the number of entries in an IN clause is set by max_allowed_packet (as others have stated) and the same restriction would apply to this.
max_allowed_packet
Related
I can imagine that question exists in some way, but I haven't found what I was looking for.
I need to remove the found values from the result I'm getting in the main query.
Consider the following:
The mainquery:
SELECT idTable
FROM tblTables
WHERE NOT IN idTables = ( **SUBQUERY HERE** )
AND dtSeats >= 4
LIMIT 1;
The subquery:
SELECT idTable
FROM tblTables,tblReservation
WHERE tblTables.idTable = tblReservation.fiTable
AND fiTime = 1
AND dtResDate = "2020-06-16"
In the tblTables there are idTable and dtSeats.
In the tblReservation are fiTime and dtResDate.
The subquery can get up to three rows.
I need to get the first free table with the lowest number of seats possible.
Thanks for helping me out!
Having the DDL and some sample data would be helpful, but I think what you are looking for is a NOT EXISTS clause. It returns everything in the outer query that doesn't match with a record in the inner query.
SELECT idTable
FROM tblTables tt
WHERE NOT EXISTS (
SELECT NULL FROM tblReservation tr WHERE tt.idTable = tr.idTable AND
tr.dtResDate = '2020-06-16'
)
AND dtSeats >= 4
ORDER BY tt.dtSeats
LIMIT 1
I have this table.
In MySql I want select this user IF key column do not have custom row AND IF key column have custom row -> value column = yes.
This is my query, but it do not work:
where `value` = if(`key` = 'custom', 'yes', '')
you can use the following statement which select any row has key not equal 'custom' or equal 'custom' and value equal 'yes'
Select * from tableName where `key`<> 'custom' or (`key` = 'custom' and `value` = 'yes')
The specification for the query isn't clear, in that it's open to several different interpretations.
I'm thinking the question is about how to return a particular result, not really about using an IF() function in the WHERE clause. (None of the SQL below uses an IF() function in a WHERE clause.)
Here's one possible interpretation of the specification:
By "select this user", we'll take that to mean we want to return a single copy of the user_id column.
By "IF key column do not have custom row", we'll take that to mean that there does not exist such a row for this user_id, then return this user_id. If such a row does exist, then do not return the user.
By "AND IF key column have custom row -> value column = yes.", we'll take that to mean to return this user_id if there is a row for this user_id that matches the condition.
Based on that interpretation, here's an approach to satisfying the specification using conditional aggregation:
SELECT t.user_id
FROM this_table t
GROUP
BY t.user_id
HAVING SUM(1) = SUM(IF(t.key='custom',IF(t.value='yes',1,0),1))
The expression inside the SUM() aggregate gets evaluated for each row. That expression is designed to return either a 1 or a 0, depending on whether the row matches the specified conditions. The SUM() aggregate totals up those 1s and 0s. And then we compare the result to the total number of rows. That tells us if a "matching" row exists or not.
The counts are by user_id, as identified in the GROUP BY clause.
The MySQL IF() function can be replace with a more portable ANSI CASE expression
HAVING SUM(1) = SUM(CASE
WHEN t.key = 'custom'
THEN CASE
WHEN t.value = 'yes'
THEN 1
ELSE 0
END
ELSE 1
END
)
If the intent is to return all of the detail rows for a user, but excluding all user_id that meet the specification, we could use an EXISTS correlated subquery:
SELECT t.user_id
, t.key
, t.value
FROM this_table t
WHERE NOT EXISTS ( SELECT 1
FROM this_table r
WHERE r.user_id = t.user_id
AND r.key = 'custom'
)
OR EXISTS ( SELECT 1
FROM this_table q
WHERE q.user_id = t.user_id
AND q.key = 'custom'
AND q.value = 'yes'
)
This is my query to get filter data from user table where category will fetch from another table.
SELECT * FROM jobfia_users
WHERE country_id='4'
and user_id IN (SELECT worker_id
FROM jobfia_worker_skills
WHERE skill_id = '42'
)
This is not giving any error, but not return any row also.
while there are lots of records are available in table using this filter.
Can any one help please ?
Additionally to the quotes surrounding your INT ids, your query will be better expressed like this :
SELECT u.*
FROM jobfia_users u
INNER JOIN jobfia_worker_skills ws
ON ws.worker_id=u.user_id AND ws.skill_id = 42
WHERE u.country_id=4
If your country_id and skill_id are int type, remove ' around values.
SELECT * FROM jobfia_users
WHERE country_id=4
and user_id IN (SELECT worker_id
FROM jobfia_worker_skills
WHERE skill_id = 42
)
Tested your code with and without '' and it works. Make sure you have data and you did not misspell some column name.
Maybe you have collision of some column names. Try to use this syntax:
\`table_name\`.\`column_name\`
Code:
SELECT *
FROM `jobfia_users`
WHERE `jobfia_users`.`country_id`='4'
AND `jobfia_users`.`user_id` IN (SELECT `jobfia_worker_skills`.`worker_id`
FROM `jobfia_worker_skills`
WHERE `jobfia_worker_skills`.`skill_id` = '42')
I know that this must be a very basic question, but I've not found an answer.
As the title says, I would like the query the record that holds the max value of a specific column.
I use the following code to achieve that:
SELECT * FROM `table_name` ORDER BY `column_with_specific_max_value` DESC LIMIT 1
I would like to know if there is an other way to achieve the same result (more parsimonious)? I know that SQL has a function MAX(column) but it's not working the way I want. I tried this:
SELECT * FROM `table_name` WHERE `column_with_specific_max_value`=MAX(`column_with_specific_max_value`)
and this:
SELECT *, MAX(`column_with_specific_max_value`) FROM `table_name`
What happen if the column_with_specific_max_value has 2 rows with the same max value? will it return both rows?
What about?
select * from table1
where score in (select max(score) from table1)
Or even without a max:
select * from table1
where score >= all (select score from table1)
Any of those WILL return all rows with the max value. You can play with it here.
If your table has an auto-increment column to work with, you could do something like...
select
YT3.*
from
( select
MAX( YT2.AutoIncColumn ) as ReturnThisRecordID
from
( select max( YT1.WhatColumn ) as MaxColumnYouWant
from YourTable YT1 ) JustMax
Join YourTable YT2
on JustMax.MaxColumnYouWant = YT2.WhatColumn ) FinalRecord
JOIN YourTable YT3
on FinalRecord.ReturnThisRecordID = YT3.AutoIncColumn
I would also ensure this is a column that SHOULD have an index on it, otherwise, you'll always be doing a table scan.
I have an array of products IDs and I need to find the IDs that are not present in the database. Sure I can do it like this:
// IDs in database: 1, 2, 3, 4, 5.
$products = array(4, 5, 6, 7);
$in_db = $db->exec("SELECT `id` FROM `table` WHERE `id` IN (" . implode($products) . ");");
$in_db_ids = array();
foreach($in_db as $i){
$in_db_ids[] = $i['id'];
}
$missing = array_diff($products, $in_db_ids);
But this is long and boring. I thought also about something like this:
// this query would be generated with PHP using an implode or something
$query = "
SELECT `t`.`id` as `missing`
SELECT 4 as `id` UNION SELECT 5 UNION SELECT 6 UNION SELECT 7
LEFT JOIN `table` USING(`id`)
WHERE `missing` is NULL;
";
$missing = $db->exec($query);
But this is so inelegant.
I think there should be a proper way to write that SELECT x UNION SELECT y UNION SELECT z, or there may be another nice way to do this check.
What do you think, guys?
To do it in the MySQL database, you will need a table or a temporary table that has a number of rows equal to the highest index in the table you are scanning for missing blanks. There is no way around this -- MySQL always "loops" through tables, it isn't a procedural language where you can set up your own loop.
That being said, if you create or have a table of sufficient size, you can create the natural number sequence using a user variable. Let's call the big table bigtable (it doesn't matter what columns are in it - we just need a name of one of the columns - I use 'acolumn').
set #row = 0;
select n from
(select #row := #row + 1 as n from bigtable) as t
left join mytable on mytable.id = t.n
where mytable.acolumn is null;
Let me know if this needs a little more explanation.