Using a string function to display specific data - mysql

I'm looking for a string function that will display data from my table where 2 values end in 1.
For example
int_id int2_id
101 302
201 301
Here the data I would want to show is the 201/301 due to the fact that they both end in 1.
Any help would be greatly appreciated.

SELECT * FROM `myTable` WHERE `int_id` LIKE '%1' and `int2_id` LIKE '%1';
The % character is a wildcard character that matches anything.

SELECT * FROM myTable WHERE RIGHT(int_id, 1) = 1 AND RIGHT(int2_id, 1) = 1

Use modular arithmetic:
SELECT * FROM `table` WHERE int_id % 10 = 1 AND int2_id % 10 = 1

Related

how can i define 2x WHERE

current query:
SELECT * FROM `invoices2` WHERE `status` = 2
I need to select status 1 and status 2, how can I do it?
I already tried things like 2 AND 1 or WHERE 'status' = 2 AND WHERE 'status' = 1
Thank you guys!
All you need is:
WHERE status IN (1, 2)
To be clear, this is equivalent to:
WHERE status = 1 OR status = 2;
You can have very complex expressions in the WHERE clause.
You can also do:
SELECT * FROM `invoices2` WHERE `status` = 1 OR `status` = 2
In single query you always have only one WHERE keyword and then you can extend it by adding OR, AND, NOT.
If they are in different rows you need and for more Status values its own extsts
SELECT * FROM `invoices2`
WHERE `status` = 2 AND EXISTS (SELECT 1 FROM `invoices2` WHERE `status` = 1)

Where condition is not working

I have a SQL query. But that contains a where condition, and the OR in that where is not working.
Query
SELECT `st_student`.`st_id`, `ab_date`, `as_date` `st_status`
FROM (`st_student`)
WHERE `st_status` = 1
OR `st_status` = 2
AND `ab_date` BETWEEN '08/01/2015' AND '08/31/2015'
OR `as_date` BETWEEN '08/01/2015' AND '08/31/2015'
AND `aca_no` = 2
GROUP BY `st_student`.`st_id`
This condition is not working:
OR `as_date` BETWEEN '08/01/2015' AND '08/31/2015'
Is there any mistake in that?
One possible error concerns the use of the AND and OR operators, since AND has priority over OR, and your query can be interpreted in the wrong way. So you should use the parentheses, and write something like this:
SELECT `st_student`.`st_id`, `ab_date`, `as_date` `st_status`
FROM `st_student`
WHERE (`st_status` = 1 OR `st_status` = 2)
AND (`ab_date` BETWEEN '08/01/2015' AND '08/31/2015'
OR `as_date` BETWEEN '08/01/2015' AND '08/31/2015')
AND `aca_no` = 2
GROUP BY `st_student`.`st_id`
In case that your columns are declared as a varchar datatype you will need to use str_to_date function. Varchar cannot be compared as a date unless you convert it to one. Try this and let me know. Best of luck.
SELECT `st_student`.`st_id`, `ab_date`, `as_date` `st_status`
FROM `st_student`
WHERE (`st_status` = 1 OR `st_status` = 2)
AND STR_TO_DATE(`ab_date`,'%d/%m/%Y')
BETWEEN
STR_TO_DATE('01/08/2015','%d/%m/%Y')
AND
STR_TO_DATE('31/08/2015','%d/%m/%Y')
OR
STR_TO_DATE(`as_date`,'%d/%m/%Y')
BETWEEN
STR_TO_DATE('01/08/2015','%d/%m/%Y')
AND
STR_TO_DATE('31/08/2015','%d/%m/%Y')
AND `aca_no` = 2
GROUP BY `st_student`.`st_id`

Convert searched case to simple case else

I've the following code
select * from weeks
where case
when wet>1000 then wenumber=1
when wet>500 then wenumber=2
when wet>100 then wenumber=3
else wenumber= 22
end
it gives me the result of both ( when > 1000 and else )
through my search I understood that it is search case, but
I need to make it a simple case
simply if the first condition were true stop evaluating "else" statement
any help
Better way of doing it
select *
from weeks
where ( wet>1000 and wenumber = 1 ) or wenumber = 22
Try this:
SELECT *
FROM weeks
WHERE wenumber = CASE WHEN wet > 1000 THEN 1
WHEN wet BETWEEN 500 AND 1000 THEN 2
WHEN wet BETWEEN 100 AND 500 THEN 3
ELSE 22
END;
You need to specify which column should be compared with result of CASE like:
SELECT *
FROM weeks
WHERE wenumber = (CASE
WHEN wet > 1000 THEN 1
ELSE 22
END)

Separate string into columns

Data :
Tree Depth
URL1||URL2 2
URL2||URL3 2
URL3||URL4||URL5 3
URL1||URL2||URL3 3
In the above data the Tree column consists of string separated by "||". I need to convert the above data such that I have 3 columns (since the max depth is 3 in this example) , the result should look like:
COL1 COL2 COL3 DEPTH
URL1 URL2 2
URL2 URL3 2
URL3 URL4 URL5 3
URL1 URL2 URL3 3
In the above example the max depth is 3 however in real world it could be N number.
Good day,
In first glance it is look like we need to use user defined SPLIT function but since number of values that you have in each string is not more then 4, there is a much simpler and probably much better solution. We just need to use the built-in PARSENAME function.
I did not test the code but the solution should be something like this:
SELECT PARSENAME(REPLACE(Tree,'||','.'), 1) as col1, PARSENAME(REPLACE(Tree,'||','.'), 2) as col2, PARSENAME(REPLACE(Tree,'||','.'), 3) as col3, Depth
from TableName
I replace the || with dot, since PARSENAME parse names that split by dot. this is the trick :-)
I actually mentioned example like this in my lecture at the sqlsaturday #360. You can see the presentation. The lecture was about WHY to use SQLCLR, and not less important WHEN to use it over transact-SQL. but I also talked about when NOT to use it, and this was one of the examples there.
In any case! if you are going to use SPLIT function then you should use SQLCLR and not T-SQL, as you can see here.
Try this, you just need to enter your Input Table, Output Table, Delimeter and Column to split. It can handle depth of more than 3, unlike PARSENAME function.
It is tested with 100,000 records and 30 split columns. It takes 10 sec to create the desired output.
Declare #Delimiter nvarchar(10) = '||'
Declare #InputTable nvarchar(2000) = '<<input table name>>'
Declare #OutputTable nvarchar(2000) = '<<output table name>>'
Declare #ColumnToSplit nvarchar(2000) = '<<column to split>>'
Declare #lsql nvarchar(max)
Declare #treeDepth int
If Object_id('dbo.treeDepth') is not null
Drop table dbo.treeDepth
CREATE TABLE dbo.treeDepth (depth INT)
declare #ltext nvarchar(max)= 'Select max(1+(len('+#ColumnToSplit+')- len(Replace('+#ColumnToSplit+','''+#Delimiter+''','''')))/(len('''+#Delimiter+'''))) from '+#InputTable
insert dbo.treeDepth EXEC(#ltext)
Select #lsql = isnull(#lsql+',','') +
'xmlname.value(''/Node[1]/Node['+cast(number+1 as nvarchar)+']'',''varchar(1000)'') AS Col_'+cast(number+1 as nvarchar)+''
from master..spt_values where type = 'P' and number < (Select * from dbo.treeDepth)
set #lsql = '
WITH ForXML
AS
(
SELECT *,
CONVERT(XML,''<Node><Node>''
+ REPLACE('+#ColumnToSplit+','''+#Delimiter+''', ''</Node><Node>'') + ''</Node></Node>'') AS xmlname
FROM '+#InputTable+'
)
Select *, '+#lsql+' Into '+#OutputTable+' From ForXML
Alter table '+#OutputTable+'
Drop column xmlname
'
EXEC(#lsql)

Why does MySQL return rows that seemingly do not match the WHERE clause?

suppose the user input
mysite.com/profile?identity=1
mysite.com/profile?identity=dinodsja
mysite.com/profile?identity=1a
getting the value
$identity = $_GET['identity']; // identity can be user_id or user_name
and i have a simple select query:
SELECT * FROM lb_users WHERE (user_id = 'dinodsja' OR user_name = 'dinodsja') AND user_status = 1
and it works fine. but the problem is:
SELECT * FROM lb_users WHERE (user_id = '1a' OR user_name = '1a') AND user_status = 1
when I execute this query it also returns the result without satisfying the condition.
Table structure:
user_id bigint(25)
user_name varchar(50) utf8_general_ci
**
-> Is this a MySQL Bug ?
-> How can we avoid this ?
-> What will be the query ?
**
The reason for that is because the data type of the column user_ID is integer.
MySQL silently drops any trailing NON-Number (and anything that follows within) in the value and that is why 1a is equal to 1 since a will be remove in the value.
SQLFiddle Demo
I do remember having a similar problem long ago.
First some background: This is not a bug. It is actually a feature. Ok, it's one that might lead to such unexpected behaviour, but MySQL is thereby very tolerant w.r.t. user inputs, respective select queries:
mysql> SELECT 'a' = 'a ';
-> 1
mysql> SELECT 'A' = 'a';
-> 1
Therefore, with implicit type conversion, the result of, e.g, '1a' in INTEGER is 1, but also:
mysql> SELECT 0 = 'x6';
-> 1
mysql> SELECT 1 = ' 1';
-> 1
mysql> SELECT 1 = ' 1a';
-> 1
This feature is also implemented in other not statically typed languages. PHP, for instance, calls this type juggling. See the PHP String conversion rules and this example from the documentation:
<?php
$foo = "0"; // $foo is string (ASCII 48)
$foo += 2; // $foo is now an integer (2)
$foo = $foo + 1.3; // $foo is now a float (3.3)
$foo = 5 + "10 Little Piggies"; // $foo is integer (15)
$foo = 5 + "10 Small Pigs"; // $foo is integer (15)
?>
See JavaScript:
<script>
document.write(parseInt("40 years") + "<br>");
</script>
=> 40
Nevertheless, the solution to your problem is pretty easy: Just cast the integer to a char and do the comparison then:
mysql> SELECT * FROM lb_users WHERE (CAST(user_id AS CHAR) = '1' OR user_name = '1')
-> 1
mysql> SELECT * FROM lb_users WHERE (CAST(user_id AS CHAR) = '1a' OR user_name = '1a')
-> 0
mysql> SELECT * FROM lb_users WHERE (CAST(user_id AS CHAR) = 'dinodsja' OR user_name = 'dinodsja')
-> 1
I made a fiddle for everyone to try it out: http://sqlfiddle.com/#!2/c2835/14/0
Hope that helps,
-Hannes
According to your previous message
its a user input for profile. user can provide user_id or user_name.
so the input is valid. but no data. – DBK Mar 30 at 6:42
I'd recommend testing to see if its an integer and only search the user ID if it's an integer. It's really more of a workaround for mySQL not handling a STRING to INT comparison, but it should work.
declare #InputVar varchar(10)
set #InputVar = '1a'
SELECT *
FROM lb_users
WHERE
(case when isnumeric(#InputVar) = 1 then
case when (user_id = #InputVar OR user_name = #InputVar) then 1 else 0 end
else
case when user_name = #InputVar then 1 else 0 end
end =1 )
And
user_status = 1
When dealing with strings I would use 'LIKE' instead of '=' to avoid this silent type conversion madness. LIKE is made to work with strings so why not use it.
SELECT * FROM lb_users WHERE (user_id = '1a' OR user_name = '1a') AND user_status = 1
you get 1 result if you change '1a' to 1a you get this:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '1a LIMIT 0, 30' at line 1
This is not a bug, take a look at http://dev.mysql.com/doc/refman/5.0/en/where-optimizations.html
hope this helps
I think you cannot duplicate a primary key and an ID, I test that one and i come up with a running data..did you set the user_id with its attributes like:
user_id bigint(50) auto_increment primary key
this is not a mysql error.