MySQL Where 2 of x - mysql

How can i get only Lines, where 2 (or more) Where Clause of many are true?
For Example:
SELECT *
FROM A
WHERE CONVERT(AES_DECRYPT(name,'".$this->key."'),CHAR) LIKE '%".$this->escape($name)."%'"
OR CONVERT(AES_DECRYPT(name2,'".$this->key."'),CHAR) = '".$this->escape($name2)."'"
OR CONVERT(AES_DECRYPT(name3,'".$this->key."'),CHAR) = '".$this->escape($name3)."'"
OR CONVERT(AES_DECRYPT(name4,'".$this->key."'),CHAR) = '".$this->escape($name4)."'"
.....
is there a simply way to get only the results where 2 (or more) match, without creating a huge SQL Statement (each column with each other column - (name AND name2) OR (name AND name3) OR (name AND name4) OR ... )

In MySQL you can utilise the fact that it treats boolean expressions as 1 or 0 in a numeric context. Thus to check for 2 or more conditions being true, you can write
WHERE (condition 1) + (condition 2) + ... + (condition n) >= 2
Note that the parentheses around each condition are required to prevent any operator precedence issues.

Related

MySQL and PostgreSQL Row Subqueries operator

I have been little bit confused while reading MySQL documentation MySQL documentation
A row subquery is a subquery variant that returns a single row and can thus return more than one column value. Legal operators for row subquery comparisons are:
= > < >= <= <> != <=>
For "=" documentation provides good explanation:
SELECT * FROM t1 WHERE (column1,column2) = (1,1);
is same as:
SELECT * FROM t1 WHERE column1 = 1 AND column2 = 1;
But how do the ">" or "<" can compare two rows? What is "plain" variant for this operator?
create table example(a integer,b integer);
insert into example values (1,1);
insert into example values (1,2);
insert into example values (2,1);
select * from example where (a,b) > (1,1)
a | b
-----
1 | 2
2 | 1
Playground: http://www.sqlfiddle.com/#!9/88641/2
p.s.:
PostgreSQL have same behaviour.
Oracle fail with error "ORA-01796: this operator cannot be used with lists "
MySQL and PostgreSQL has same behaviour, let's read postgres documentation
The = and <> cases work slightly differently from the others. Two rows are considered equal if all their corresponding members are non-null and equal; the rows are unequal if any corresponding members are non-null and unequal; otherwise the result of the row comparison is unknown (null).
For the <, <=, > and >= cases, the row elements are compared left-to-right, stopping as soon as an unequal or null pair of elements is found. If either of this pair of elements is null, the result of the row comparison is unknown (null); otherwise comparison of this pair of elements determines the result. For example, ROW(1,2,NULL) < ROW(1,3,0) yields true, not null, because the third pair of elements are not considered.
So (a,b) = (c,d) evaluated as
a = c and b = d
But (a,b,) < (c,d) evaluated as
a < b or (a=c and b < c)
It's look very strange. And I have no guess how will be evaluated comparation of rows with 3 of more attributes;

SQL WHERE condition, why the result using 'a != 7 and b !=836' is not equal ' !(a=7 and b=836)'?

There are three records like:
a=7 , b=836
a=8 , b=836
a=7 , b=839
I want to get the result without (a=7 and b=836).
the result is empty when execute the sql like select * from test where a!=7 and b!=836,
but it got the correct result by using select * from test where a<>7 or b<>836.
I have two questions:
Why 'a!=7 and b!=836' not equal !(a=7 and b=836)?
What's the different between the two conditions ?
'a!=7 and b!=836' and 'a<>7 or b<>836'
The difference is in your logic operators, and and or, in combination with parentheses.
select * from test where a!=7 and b!=836
This query would select where BOTH of your statements return true, that is both a is not 7, and b is not 836. This would return nothing, there is no record where both of these are true.
select * from test where !(a=7 and b=836)
When you put the parentheses around your and, you move the logic around. That statement means that all records NOT matching any record where both a is 7 and b is 836. So inside the parenthesis it matches the first record, then it inverts that selection.
select * from test where a<>7 or b<>836
The <> is the same as != (Link to documentation). But in this query you use or. So it will match any record where a is not 7, AND any record that is not 836. So would match both second and third row.
For more reading material, take a look at the De Morgan's Laws. !(a and b) equals !a or !b. More explanation here and here.
Actually != and <> exactly the same. See the documentation.
<> is sql standard, != non-standard.
http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#operator_not-equal

How to combine CONCAT() and WHERE in MariaDB?

I like to use the result from another query to address the column name. For this I like to use CONCAT(). But somehow it don't work; when I run this line I get 0 rows back:
SELECT * FROM cover WHERE CONCAT('c','9') = 1;
When I don't make use of CONCAT() it work perfectly:
SELECT * FROM cover WHERE c9 = 1;
And also CONCAT() seems to work. With this I get a result:
SELECT CONCAT('c','9');
I tried all solution from this question:
MySQL select with CONCAT condition
like this one, but i always got 0rows back:
SELECT * FROM (
SELECT id, CONCAT('c', '9') as target
FROM cover) base
WHERE target = "1"
My MySQL Version is; 10.1.16-MariaDB
It is bad schema design to splay an array across a bunch of columns. And, as you are discovering, it is hard to use the columns. Build another table for the c values.
Or...
With lots of 0/1 "columns", consider SET or BIGINT UNSIGNED; either will hold up to 64 boolean flags in a tiny fraction of the space. And, with different code, BLOB could be used.
To extract bit 22 from a BIGINT, ((col >> 22) & 1) will give you 0 or 1.
Consider using a case when, since the number of options is known beforehand (you can only access columns that exist):
SELECT id
FROM cover
WHERE case ?
when 1 then c1
when 2 then c2
when 9 then c9
end = 1
... where the question mark would be the provided value, like 9 in your example.

Mysql select, if input arguments are same dont return any rows

I have a bit of an odd mysql query I need to run.
I am passing two arguments to a WHERE clause, $source and $destination (via php). I want mysql to simply return nothing if $source and destination are the same number. Otherwise do the lookup in the DB and pull the record.
Query:
SELECT count(id) AS count
FROM approval
WHERE source=1 AND destination=2 AND approved!=0
Now this will return all rows where source is one and destination is two.
BUT! I want it it to return nothing if source and destination are the same number.
Some rows in certain cases may contain the same number, but that happens in a different potion of the code, in this specific select I want it only to perform the search if source and destination are different. I looked at comparison operators but those all seem to be checking the argument against a value in the column, rather than an argument against an argument.
I think this query does what you want
SELECT count(id) AS count
FROM approvals
WHERE source = $source AND destination = $destination AND approved <> 0
HAVING $source <> $destination;
That would be a simple matter of including:
and source <> destination
in the query. This will exclude rows where the columns are the same which, because of the other clauses, means the arguments you've provided are the same as well.
This will probably still go out to the database but it's guaranteed to return a count of zero (assuming no NULLs of course - if you want to handle those, you'll need extra clauses with IS [NOT] NULL). If you don't even want to go out to the database if your two arguments are the same, the time to do that is in your PHP code by comparing the arguments beforehand.
By way of example, the following DDL:
create table xyzzy (a int, b int);
insert into xyzzy (a,b) values (1,1);
creates a table with one row. When you execute the queries:
SELECT count(a) AS x FROM xyzzy WHERE a = 1 AND b = 1;
SELECT count(a) AS x FROM xyzzy WHERE a = 1 AND b = 1 and a <> b;
you'll get the rows 1 (equivalent to what you currently have) and 0 (equivalent to the change I've proposed).
If you really want to use the parameters instead of the columns, that will work as well:
SELECT count(a) AS x FROM xyzzy WHERE a = 1 AND b = 1 and 1 <> 1;
This also returns a count of zero and is equivalent to just tacking:
and $source <> $destination
onto your query. If the two numbers are identical, this will boil down to and false which will result in a count of zero.
So will either of:
and source <> $destination
and $source <> destination
for that matter.

Is there a special character in mySql that would return always true in WHERE clauses?

Is there a character, say, $,
SELECT * FROM Persons WHERE firstName='Peter' AND areaCode=$;
such that the statement would return the same as
SELECT * FROM Persons WHERE firstName='Peter'
i.e. areaCode=$ would always return always true and, thus, effectively “turns of” the criteria areaCode=...
I’m writing a VBA code in Excel that fetches some rows based on a number of criteria. The criteria can either be enabled or disabled. A character like $ would make the disabling so much easier.
instead of disabling it, pass it through to your query as NULL and use COALESCE:
SELECT *
FROM Persons
WHERE firstName='Peter'
AND areaCode = COALESCE(<your parameter>, areaCode);
%
See Wildcards
You could use NULL for this purpose:
AND (areaCode = ? OR ? IS NULL)
I think you could use something like
SELECT * FROM Persons WHERE firstName=firstName
of course without quotes
From your question I assume that you actually want the ability to include or exclude the where clause, in which case you need to use or.
SELECT *
FROM Persons
WHERE ( 1 = 2
OR ( firstName = 'Peter'
AND < more conditions if needed >
)
)
In this example 1 <> 2 so the only condition evaluated is firstName = 'Peter'. If you then want to ignore the where clause you change 2 to 1. As 1 = 1 this is evaluated for every row and the rest of the conditions will be ignored.