Sql query for multiple ANDs use in a single condition - mysql

I need an SQL query , with multiple AND's. Let me explain with an example,
For example I want to search in a database for a property , who's price is greater than 1000 and less than 2000 (price is between 1000-2000), and its area is greater than 1000 sqft. and less than 2000 sq ft. (area is between 1000-2000).
So i was guessing that the query could be,
SELECT *
FROM table_name
WHERE (price>1000 AND price<2000) AND (area>1000 AND area<2000)
this is something i need ! Thank you

Your original query looks fine to me, but you can also use BETWEEN if you like, try this:
SELECT * FROM table_name WHERE (price BETWEEN 1001 AND 2000) AND (area BETWEEN 1001 AND 2000);
expr BETWEEN min AND max
If expr is greater than or equal to min and expr is less than or equal to max, BETWEEN returns 1, otherwise it returns 0. This is equivalent to the expression (min <= expr AND expr <= max) if all the arguments are of the same type. Otherwise type conversion takes place according to the rules described in Section 12.2, “Type Conversion in Expression Evaluation”, but applied to all the three arguments

Use between instead of and
SELECT * FROM table_name WHERE (price between 1001 AND 1999) AND (area between 1001 AND 1999)

Use this, i think it will solve your problem. It works for me:
SELECT * FROM table_name WHERE price and area BETWEEN 1001 and 1999.
If we have same values of the parameters, then we can add the condition with and all the parameters.

Related

Optimize SQL with multiple BETWEENs in WHERE

I have a query like this:
SELECT [...]
FROM [...]
WHERE
FirstInt BETWEEN 100 AND 200 AND
SecondInt BETWEEN 100 AND 200
Those variables have to be in the same range. Is there any way to write sth. like "(a || b) between 100 and 200"?
I am not sure if this is what you were looking for:
SELECT [...]
FROM [...]
WHERE least(FirstInt , SecondInt, ... ) >= 100
AND greatest(FirstInt , SecondInt, ... ) <= 200
With this query you will find the smallest value of all of your columns(with function least) and compare it to the smallest value of your range. You will do the same with the largest value of all of your columns (with function greatest) and compare it to the largest value of your range.
Here is a small demo:
DEMO
With this query you can replace your multiple between statements or in other words you can use it when you want to copare multiple columns to the same range.
I may not fully understand the question but i think you can use this.
SELECT [...]
FROM [...]
WHERE
FirstInt >= 100 AND FirstInt<=200 OR
SecondInt >= 100 AND SecondInt <= 200

mysql : date format not working with OR in where condition

Whenever I'm using OR in where condition my query is putting date_format() it's working but when I'm using AND it's working fine.
True Query:
SELECT * FROM `tbl_inquiry_trans`
WHERE date_format(follow_updatetime,'%Y-%m-%d') >= '2018-08-02'
AND date_format(follow_updatetime,'%Y-%m-%d') <= '2018-08-02'
AND emp_id=2 or user_id=2
The above query should display specific date data but it's showing all dates data.
Test Query:
SELECT * FROM `tbl_inquiry_trans`
WHERE date_format(follow_updatetime,'%Y-%m-%d') >= '2018-08-02'
AND date_format(follow_updatetime,'%Y-%m-%d') <= '2018-08-02'
AND emp_id=2
When I'm using AND it's showing expected date data but I want to use OR in the where clause.
The and logical operator has a higher precedence than the or operator (i.e., and expressions are evaluated before or expressions, in a similar way you'd calculate a multiplication before calculating an addition in an arithmetic expression). In order to achieve the behavior you wanted, you need to surround the two sides of the or operator with parenthesis:
SELECT *
FROM tbl_inquiry_trans
WHERE date_format(follow_updatetime,'%Y-%m-%d')>='2018-08-02' AND
date_format(follow_updatetime,'%Y-%m-%d')<='2018-08-02' AND
(emp_id=2 OR user_id=2) -- Here
Same answer as #Mureinik, except that I don't think you need to those calls to DATE_FORMAT, because in MySQL it is possible to directly compare dates against string literals. So, the following should suffice:
SELECT *
FROM tbl_inquiry_trans
WHERE
follow_updatetime >= '2018-08-02' AND follow_updatetime < '2018-08-03' AND
(emp_id = 2 OR user_id = 2);
The logic in the above check on follow_updatetime is that any date would match if it were on or after midnight of 2018-08-02 or strictly before midnight of 2018-08-03. This would cover the entire day of 2018-08-02. This version of doing it is preferable to what you had, because it makes it possible to use an index on the follow_updatetime column.

Setting A Column to the 100th dec in SQL Query

I have a variance report query here I need the 'Variance' to not have 10 decimal points in the Variance Column. What is the most convenient way to round Variance results to the 100th?
WITH A AS
(
select
A.FACTORY,
A.JOB_NUMBER,
A.PROCESS_STAGE,
A.PART_CODE,
B.PART_DESC_1,
A.INPUT_QTY_STD,
A.QUANTITY_INPUT,
A.QUANTITY_OUTSTANDING,
A.INPUT_QTY_ACTUAL,
(A.QUANTITY_OUTSTANDING*100/NULLIF(A.INPUT_QTY_STD,0)) as variance,
A.ACTUAL_CLOSE_DATE
from
(select * from [man_prod].[dbo].[JOB_STAGE_LINES]
where JOB_NUMBER in (select JOB_NUMBER from JOB_OUTPUTS where
BF_QTY_ACTUAL<>0
and ABS(DATEDIFF(HOUR,ACTUAL_CLOSE_DATE,GETDATE())) < 12 and STATUS_FLAG='C'
)) A
join fin_prod.dbo.PRODUCT_MASTER B
ON A.PART_CODE=B.PART_CODE
WHERE
A.INPUT_QTY_STD<>0 and
A.QUANTITY_OUTSTANDING <>0
)
SELECT * FROM A WHERE A.variance >10.000000 OR A.variance <-10
order by PROCESS_STAGE asc ,PART_CODE asc, variance desc ;
The Variance column comes out at 00.0000000000 i need it to display 00.000 or 00.000000
Help is greatly appreciated
Use the MySQL ROUND() function, the second argument is the number of decimal places if it is positive.
ROUND((A.QUANTITY_OUTSTANDING*100/NULLIF(A.INPUT_QTY_STD,0)), 3) as variance,
In this example if the value is 0.0000000000 it would be rounded to 3 decimal places, or 0.000.
You can use the TRUNCATE option:
TRUNCATE((A.QUANTITY_OUTSTANDING*100/NULLIF(A.INPUT_QTY_STD,0)), 3) as variance,
or use the ROUND if you are looking for rounding(as suggested by doublesharp)
ROUND((A.QUANTITY_OUTSTANDING*100/NULLIF(A.INPUT_QTY_STD,0)), 3) as variance,
Using Convert to convert it to a decimal of the desired length is what i prefer when i am not actually rounding the value, just formatting.
CONVERT(DECIMAL(10,3),10000)

Sum all values, ignoring the minus

Ok so I have a mySQL table of values. Some are positive, some are negative. The negative ones have a - infront of them in the table. I'm using Codeigniter.
I need to sum them all together, but IGNORE the - before the negative values. I just want to sum the numbers, not sum them as negative numbers.
So for example, this is what it does currently:
-55 + -20 = 35
But what I want it to do is:
-55 + -20 = 75
Basically I want to sum the values only, regardless of their positive or negative type.
How can I do this? Here's my query:
$this->db->select_sum('vat')
->from('accounts')->where_in('type', 'Expenses')
->where('date <=', $current_period)
->where('date >=', $previous_period);
Perhaps something like this will work:
$this->db->select('SUM(CASE WHEN vat >= 0 THEN vat ELSE -vat END) AS sum', false)->from('accounts')->where_in('type', 'Expenses')->where('date <=', $current_period)->where('date >=', $previous_period);
This should keep positive numbers in vat positive and convert negative numbers to positive. Note: the false in the select() statement stops CI from auto-escaping the fields.
Also, as picked up from a comment from #shubhansh, you can use MySQL's ABS() method to get the absolute-value instead of the CASE:
$this->db->select('SUM(ABS(vat)) AS sum', false)->from('accounts')->where_in('type', 'Expenses')->where('date <=', $current_period)->where('date >=', $previous_period);
I can think of two ways.
First way: I'm pretty sure CI escapes field names, so to do it this way you need to execute normal query:
$this->db->query('SELECT SUM(AVG(vat)) FROM accounts WHERE ...'); // Replace ... with WHERE parameters
Second way: Or do two queries and sum the results:
$positive = $this->db->select_sum('vat')->from('accounts')->where_in('type', 'Expenses')->where('date <=', $current_period)->where('date >=', $previous_period)->where('vat >=', 0);
$negative = $this->db->select_sum('vat')->from('accounts')->where_in('type', 'Expenses')->where('date <=', $current_period)->where('date >=', $previous_period)->where('vat <', 0);
$result = $positive + abs($negative);
Mind that second option would take longer time to complete as those are two separate queries.
I had the same issue doing a date search on a db level - best I could do was use ABS() since time_diff returns a negative value if the result is in the past. If are working with date_diff or TIME_DIFF use this:
TIME(ABS(TIMEDIFF(TIME(sch_Starts), TIME("22:00:00"))))
it takes the possibly negative result, converts it via ABS and wrap the TIME() around that to convert back to time if u are using time specific functions like me.
Tedious perhaps but it works 100%
You could always try:
where table.field NOT LIKE '%-%'

What does the use of an asterisk (*) mean in a mysql select statement, other than a wildcard?

I came across a mysql query that looks like this:
SELECT
SUM(some_amount*(some_field!=90)*(some_date < '2011-04-22'))
, SUM(some_amount*(some_field =90)*(some_date < '2011-04-22')*(another_field IS NULL))
FROM
some_table
What does the * mean in the select statement in this case?
Looks like CAST() is not necessary for boolean-to-integer conversions. Multiplication is used to convert the sum to 0 for unwanted rows (using the fact that boolean true can be cast to 1 and false to 0):
some_amount*(some_field!=90)*(some_date < '2011-04-22')
if some_field == 90 or some_date >= '2011-04-22', the corresponding term will evaluate to 0, thereby converting the entire expression to 0.
It is a multiplication operation.
example 2*3=6
It's a standard multiplication operator,
select 2 * 2
= 4
:)