I'm reading MySQL's documentation on the assignment operators, and in the section for the := operator, it says
The value on the right hand side may be a literal value, another variable storing a value, or any legal expression that yields a scalar value, including the result of a query (provided that this value is a scalar value).
If I understand correctly, a scalar value is a value that represents a fixed value instead of a range or collection of values or an object.
Being very new to SQL in general, I don't quite understand the parenthetical statement at the end of the quote. When would the result of a query be a non-scalar value? Is it when a query simply returns multiple columns from a row in its result? If so, how can those results be used meaningfully in a MySQL script if they can't be stored in a variable?
Such a query is a scalar subquery. Such a subquery has two important properties:
The subquery returns exactly one column.
The subquery returns at most one row.
If the subquery returns no rows, then the assigned value is NULL.
That is a subquery. You can assign multiple values using SELECT and :=:
select #var1 := col1, #val2 := col2
from . . .;
A scalar value has one column and one row. You can't assign such multi-valued results to a MySQL session variable.
But you can assign multiple columns to multiple variables.
SELECT a, b, c FROM mytable INTO #varA, #varB, #varC;
See http://dev.mysql.com/doc/refman/5.7/en/select-into.html for more details.
Related
I want to obtain unread messages count from MySQL database using SELECT SUM operator.
So, my SQL is:
SELECT sum(status_field = 'new') unreadMessagesCount
FROM messages
WHERE 'author_uid' = 'authorUID'
And it returns NULL. Why?
I have items in database and I can select it by (SELECT * FROM messages)
It returns NULL because you are comparing strings, not columns with:
WHERE 'author_uid' = 'authorUID'
And these two strings are not equal. So, all rows are filtered out. The NULL value is because you have an aggregation query. SUM() returns NULL when there are no rows in such a query.
I'm not sure what you intend. Perhaps:
WHERE author_uid = 'authorUID'
However, 'authorUID' seems like a strange value for a uid. You need to put an appropriate value there. If it is a string, enclose it in single quotes. If it is a number, do not use single quotes.
I am new to COALESCE function in REDSHIFT. I ran below four queries in mysql and Redshift.
1st and 2nd query executed as expected in both mysql and redshift. But for 3rd and 4th query I am getting two different results in mysql and Redshift. How does this behave?
select COALESCE(null,null,1) -> 1
select COALESCE(null,null,'John') -> 1
select COALESCE(null,null,1,'John') -> (Redshift : error , mysql:1)
select COALESCE(null,null,'John',1) -> (Redshift: error, mysql:John)
Also this query should give error in mysql but it has succeeded
Any help is appreciated
Amazon Redshift Database Developer Guide claims:
An NVL expression is identical to a COALESCE expression. NVL and
COALESCE are synonyms.
Syntax
NVL | COALESCE ( expression, expression, ... )
An NVL or COALESCE expression returns the value of the first expression
in the list that is not null. If all expressions are null, the result
is null. When a non-null value is found, the remaining expressions in
the list are not evaluated.
This type of expression is useful when you want to return a backup
value for something when the preferred value is missing or null. For
example, a query might return one of three phone numbers (cell, home,
or work, in that order), whichever is found first in the table (not
null).
If you obtain the error this may mean that the returned value datatype do not match the datatype of recordset field or any another structure which must accept the returned value.
PS. Will you show error messages?
Though it is not written in the documentation, but coalesce works on the compatible data types. Integer and varchar cannot be compared.
The error becomes more evident when you provide column name instead of hard-code values. Try executing this:
select coalesce(integer_column, varchar_column) from a_table;
You would get an error saying something like this:
coalesce types integer and varchar cannot be matched.
Got this QueryBuilder in one of my repositories.
$query = $em->createQueryBuilder('d')
->select('d, i, u, SUM(CASE WHEN t.user = :userId THEN 1 ELSE 0 END) as myTickets')
->leftJoin('d.item','i')
->leftJoin('d.users','u')
->leftJoin('d.tickets','t')
->where('d.active = 1')
->andWhere('d.state = 1')
->setParameter('userId',$user->getId())
->orderBy('d.dateFinish', 'ASC');
When i execute the code, MySQL throws me this error.
Key "premium" for array with keys "0, myTickets" does not exist
"premium" is a field of "d".
How can i recive the fields with the custom SUM?
Since you're using aggregate function in your query, you get the so called mixed result. Mixed result normally return your object fetched with your FROM clause as zero index [0]. The rest of your result is populated based on the aliases you set for your custom fields.
$result[0] will return the object you want to access.
$result['myTickets'] will return the result of your aggregate function. In this case, it's a SUM.
A quote from documentation:
SELECT u, UPPER(u.name) nameUpper FROM MyProject\Model\User u
This query makes use of the UPPER DQL function that returns a scalar value and because there is now a scalar value in the SELECT clause, we get a mixed result.
Conventions for mixed results are as follows:
The object fetched in the FROM clause is always positioned with the key ‘0’.
Every scalar without a name is numbered in the order given in the query, starting with 1.
Every aliased scalar is given with its alias-name as the key. The case of the name is kept.
If several objects are fetched from the FROM clause they alternate every row.
You can read more about this topic here.
I'm trying to run a SQL SELECT statement against a column that is of type SET. The table is called myTable and the columns in myTable are called base_props and names. The base_props column is of type SET. The values in base_prop are vb,nt, cnt,poss and loc. So I would like to SELECT entries from the column 'name' where base_props have both the values, vb and poss. The results I'm looking to get may have values other than just vb and poss. So to be clear I would like to select all entries that have the values vb and poss regardless if they have other values as well. I've tried the following SQL queries but I can't get the desired results.
SELECT name from myTable WHERE base_props = 'vb' AND base_props = 'poss'
That query returns an empty result set. I've tried using FIND_IN_SET() and IN() but I couldn't get anywhere with that. I've written SQL statements before but never had to deal with columns that are type SET. Any help is appreciated.
The only thing I can come up with is using the LIKE keyword:
SELECT name FROM myTable WHERE (base_props LIKE '%vb%' AND base_props LIKE '%poss%');
This will make sure both vb and cnt are in the base_props column. Of course you can use cnt, nt and loc in there, or any number of base_props values in the sql, just add more AND statements.
OR as a deleted answer by samitha pointed out, you can use FIND_IN_SET:
SELECT name from myTable WHERE FIND_IN_SET('vb', base_props) AND FIND_IN_SET('poss', base_props);
Comment (by spencer7593): "both of these work, but there is a slight difference. The LIKE operator will actually match any member that includes the search string anywhere in a term; the FIND_IN_SET function will only match an exact member. It's also possible to search for members in set by the order they appear in the SET definition, using the MySQL BITAND operator: for example, to match the 1st and 4th members of the set: WHERE base_props & 1 AND base_props & 8". So for example, if you have 'a' and 'aaa' in your set, then using the LIKE "%a%" method will also return rows containing 'aaa'.
Conclusion: use the FIND_IN_SET solution since it will work for all cases.
FIND_IN_SET return index, Try this
SELECT name from myTable WHERE FIND_IN_SET(base_props, 'vb') > 0 AND
FIND_IN_SET(base_props, 'poss') > 0
What I'm Using: The most recent MySQL on Ubuntu 12.
The Set Up: Suppose I have a table "EmployeePayment" with "Name" and "Hours" for each employee. Suppose I already have it populated with values.
The Question: When I use the command
select * from EmployeePayment where Name in ('');
I get the empty set, as I'd expect. But, when I use
select * from EmployeePayment where Name in ('' or '');
I get the entire table returned. Moreover, if I'm picky and put in the command
select Name, SUM(Hours) from EmployeePayment where Name in ('' or '');
then it only returns whatever is the top name from the table. What's happening with this "in" command?
First off, you need to get rid of the or, the proper syntax for the in clause uses commas to separate the possibilities, such as:
sql> select name from people where status in ('intelligent', 'good looking')
pax
1 row returned
What your current variant is doing is applying the or operator to give you a one-element in-list. See here for more detail.
The reason why you're only getting one row for the aggregated query is because you have no group by clause, so you're grouping all rows. Most DBMS' would then complain about having a non-aggregated column that isn't part of the grouping, but MySQL is a bit fancy-free and footloose with the rules in that regard.
It's obviously grouping over the whole table (as it should) but applying some default aggregating function to the name (which it probably shouldn't, but does according to its documentation).
This MySQL extension is covered here but heed the warning: MySQL can choose any of the myriad possible values for these non-aggregated, non-group-by columns, so it's more useful when you know that all the rows in a given group share the same value for the column.
You're effectively doing this:
select * from EmployeePayment where Name in (0);
The OR expression evaluates to 0, and WHERE Name IN (0); returns all rows. You have to use the proper IN syntax as suggested in the other answers:
SELECT * FROM EmployeePayment WHERE Name IN ('foo', 'bar');
IN uses comma separated values, for example: WHERE Name IN ('tim','beth')
So try WHERE Name IN ('','');
But more importantly, why would you want to check where a value is empty or empty? Or was that just to get the question across?
http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#function_in