MSSql ISNULL query - sql-server-2008

select ISNULL(c.name,'any') from (select Name from Orders where ID = '123')
select ISNULL((select Name from Orders where ID = '123'),'any')
Orders table have two columns
1. ID
2. Name
and data in Orders is
ID Name
121 abc
124 def
First Query is not returning any result whereas second query is giving any as result. What is the difference

The first form uses a subquery as a table source, in its FROM clause; it can return between zero and many rows.
For each of the rows that the subquery returns, the ISNULL expression is evaluated. But if the subquery returned no rows, then the final output contains no rows.
The second form uses a SELECT without a FROM clause - which will always produce a result set containing exactly one row. It then also uses a scalar subquery (by introducing a subquery in a location where a scalar value is expected) - that has to either produce zero or one results. If the subquery produces zero results, then NULL is substituted.
So, the differences between the two are that the first query can return between zero and many rows, and the ISNULL expression is evaluated for each row. Whereas the second query always produces exactly one row, and if the subquery returned multiple results, an error is produced.

Related

Why is only one result showing from my query?

Why am I only getting one result from the query below? The suggested "answer" has the first name "Susan" instead of what I got in my results.
SELECT EmpFirstName, EmpLastName, p.ProductName as ProductName,
YEAR(c.OrderDate) AS Year,
SUM(o.QuotedPrice + o.QuantityOrdered) AS TotalValue
FROM Employees
NATURAL JOIN Products p
NATURAL JOIN Order_Details o
NATURAL JOIN Orders c
ORDER BY Year, TotalValue DESC
Image of results
Image of Table Structure
Because there are a Sum in your Query
The result returned by the query does not match your expectations because the query is invalid. And your expectations are incorrect.
The presence of an aggregate (GROUP BY) function in the expression from the SELECT clause requires the presence of a GROUP BY clause. When such a clause does not exists, the SQL standard automatically adds a GROUP BY 1 clause that produces only one group from all the selected rows.
Each expression that appears in the SELECT clause of a GROUP BY query must follow one of these rules, in order to have a valid SQL query:
it also appears in the GROUP BY clause;
it's a call to an aggregate (GROUP BY) function;
is functionally dependent of one column that appears in the GROUP BY clause.
Because your query does not have a GROUP BY clause, the expressions EmpFirstName, EmpLastName, p.ProductName and YEAR(c.OrderDate) are not valid in the SELECT clause.
Before version 5.7.5, MySQL used to allow such invalid SQL queries but it reserved its privilege to return indeterminate values for the invalid expressions.
Since version 5.7.5, MySQL handles such queries correctly and rejects them. Other RDBMS-es handle them correctly since many years ago.
The explanation for the indeterminate values is simple: the JOIN and WHERE clauses extract some rows from the table(s). The (missing) GROUP BY clause produces only one record from all these rows. A GROUP BY query never returns rows from the table, it generates the values it puts in the result set. Since there are multiple different values for EmpFirstName in the group, the SQL standard says the query is invalid. MySQL used to ignore the standard but it had no valid rule about what value to pick from the EmpFirstName expression in the SELECT clause. Any value from the rows in the group is equally valid and that's what it returns: one random value from the group.
In order to get the results you expect you have to group the rows by OrderNumber and ProductNumber (and EmployeeID to get a valid SQL query):

LEFT JOIN returns everything with NULL

I have two tables whome I am joining through left join. Both the tables are empty. But when I run the query, mysql returns a row with all NULLS.
I have tried several queries like
SELECT products.*,SUM(pq_quantity) as quantity
FROM `products` LEFT JOIN `products_quantities` ON `pq_product_idFk` = `p_id`
WHERE `p_volusion_id` = '37808'
OR
SELECT products.*,SUM(pq_quantity) as quantity
FROM `products` LEFT JOIN `products_quantities` ON `pq_product_idFk` = `p_id`
WHERE `p_volusion_id` = '37808' AND p_id IS NOT NULL
OR
SELECT products.*,SUM(pq_quantity) as quantity
FROM `products` LEFT JOIN `products_quantities` ON `pq_product_idFk` = `p_id` AND `p_volusion_id` = '37808' AND p_id IS NOT NULL
NONE of the above queries seem to work as I just want the result that is not NULL.
Thanks
Both the tables are empty. But when I run the query, mysql returns a row with all NULLS.
The presence of GROUP BY aggregate functions in the SELECT clause asks the GROUP BY clause to be present too. However, if it is not present, the SQL standard specifies that a single group is to be created using all the rows filtered by the WHERE clause.
Because of the * used in the SELECT clause, all the queries you posted are invalid SQL.
A query that contains a GROUP BY clause does not return rows from tables. It creates rows using the values extracted from the tables. First it creates groups (and sub-groups) using the expressions from the GROUP BY clause. All the rows from a group have the same value for the first expression specified in the GROUP BY clause.
If there are two or more expressions in the GROUP BY clause, each group is split into sub-groups using the second expression then each sub-group is further split into sub-sub-groups using the third expression (if exists) and so on.
From each such group of rows (after the last split), the database engine generates one new row and puts it into the result set. If the query contains in the SELECT clause expressions that are not either arguments of a GRUP BY aggregate function or also present in the GROUP BY clause then, most probably, these expressions will have more than one value in a subgroup. This is why the query is invalid SQL. Up to version 5.7.5, MySQL accepts such invalid queries but reserves itself the right to return any value it wants (from the group) for the offending expressions.
Back to your question, as explained above, even without having a GROUP BY clause, your query is processed as it had one and one group is created from all the rows filtered by the WHERE clause.
It is an empty group but this doesn't prevent the database engine to generate a row from it. Since there are no values to use to compute SUM(pG_quantity), NULL is the logical value it returns in the columns of the result set.
NULL is a special value that means the absence of any value or an unknown value. It make perfect sense in your case. You don't have any value in the tables, there is no way one could compute SUM(pq_quantity). Its value is not available (i.e. NULL).

Why MySQL COUNT without table name gives 1

could you please explain why mysql count function without providing any table name gives 1 as value?
SELECT COUNT(*);
Result: 1
Because in mysql select constant_value command is valid (such as select 2 will return 2) and will return 1 row. Count() function without group by will collapse the resultset and count the number of items in the resultset. In this case 1 row would be returned and count(*) counts that.
Normally all selects are of the form SELECT [columns, scalar computations on columns, grouped computations on columns, or scalar computations] FROM [table or joins of tables, etc]
Because this allows plain scalar computations we can do something like SELECT 1 + 1 FROM SomeTable and it will return a recordset with the value 2 for every row in the table SomeTable.
Now, if we didn't care about any table, but just wanted to do our scalar computed we might want to do something like SELECT 1 + 1. This isn't allowed by the standard, but it is useful and most databases allow it (Oracle doesn't unless it's changed recently, at least it used to not).
Hence such bare SELECTs are treated as if they had a from clause which specified a table with one row and no column (impossible of course, but it does the trick). Hence SELECT 1 + 1 becomes SELECT 1 + 1 FROM ImaginaryTableWithOneRow which returns a single row with a single column with the value 2.
Mostly we don't think about this, we just get used to the fact that bare SELECTs give results and don't even think about the fact that there must be some one-row thing selected to return one row.
In doing SELECT COUNT() you did the equivalent of SELECT COUNT() FROM ImaginaryTableWithOneRow which of course returns 1.
Reference

MySQL joins: why is this returning a row?

I have the below query. The email and pass specified do NOT correspond to any row in the table, so it should return no rows, which is what happens.
SELECT *
FROM _users
LEFT JOIN _assocs ON
item_id = _users.id AND
item_type = "_users.user_group" AND
foreign_item_type = "_user_groups"
WHERE
email = 'some#email.com' AND
password = 'somepass' AND
activation_key IS NULL
LIMIT 1
However, when I modify the SELECT part to
SELECT GROUP_CONCAT(foreign_item_id) AS user_groups
...it always returns a row, regardless, with the columns all having null values. Why?
I'm using a left join specifically because it's possible nothing will be returned from table 2 (_assocs).
The function group_concat() is an aggregation function (such as MIN(), MAX(), SUM() and AVG()).
This turns the query into an aggregation query, with no group by clause. For such a query, all the rows are considered as a single set and one row is returned to summarize them. These is even true when the result set has no rows. As you have found, the result is one row with NULLs in the columns.
According to mysql docs, when no non-null value is provided for GROUP_CONCAT function, the return value is null,

func.count(distinct(...)) does not give the same result as distinct().count()

I have a column with null entries, e.g. the possible values in this column are None, 1, 2, 3
When I count the number of unique entries in the column with session.query(func.count(distinct(Entry.col))).scalar() I get back '3'.
But when I perform the count with session.query(Entry.col).distinct().count(), I get back '4'.
Why does the latter method count the None, but the first doesn't?
In the first case, the resulting query will look like this:
SELECT COUNT(DISTINCT(col)) FROM Entry
... and, as you probably already know, COUNT here won't actually count the NULL values.
In the second case, however, the query is different, as shown in the doc:
SELECT count(1) AS count_1 FROM (
SELECT DISTINCT(col) FROM Entry
) AS anon_1
Now that just counts the total number of the rows returned by SELECT DISTINCT query (which is 4 - NULL is included in the output of DISTINCT queries).
The reason is simple: query.count purpose is to return the number of rows the query would have returned if run without count clause. This method doesn't give you control over which columns should be used to count - that's what func.count(...) is for.
MySQL COUNT doesn't count NULL values, so if you are counting values by a field that has NULL values, that rows won't be counted by COUNT.
DISTINCT returns just number of different values so NULL is included.