Order by first non-null result that comes from two different columns - mysql

I want to browse through all values of two columns in a table:
if the value in column 1 is not null, select it, otherwise select the value in column 2 instead.
then sort the final result in alphabetical ascending order, wherever column its values came from.
I tried the following query but it doesn't work and I'm not even sure it is supposed to do what I want to do.
SELECT *
FROM table
ORDER BY (CASE WHEN col1 IS NOT NULL THEN 1 ELSE 2 END ),
col1 DESC,
col2 DESC)
Besides the fact that it doesn't work (nothing outputted), it seems to sort the values of each column separately while I want to sort the final set of values retrieved, regardless of the column they are from.
Thank you for your help.

If you want to fix it with the CASE expression, it'd look like the following:
SELECT *,
CASE WHEN col1 IS NOT NULL
THEN col1
ELSE col2
END AS col
FROM table
ORDER BY col
Although a nice option is using the COALESCE function. It returns the first non-null value in the list of arguments.
SELECT *, COALESCE(col1, col2) AS col
FROM table
ORDER BY col

Related

Generate MQsql query to get records

I am having the following table say "A"
"column1" "column2"
1 arafath#gmail.com
2 ram#gmail.com;arafath#gmail.com
3 tom#gmail.com
I want to get the records with the following condition.
Condition1:
If the column value exist in the any of the row, it will retrieve the matched rows
Condition2:
If the column value doesn't match with any of the row, it wants to retrieve all the rows
Eg: column2 = "ram#gmail.com"
Output should be "row 2"
Eg: column2 = "arafath#gmail.com"
Output should be "row 1, row 2"
Eg: column2 = "xxx#gmail.com" (Unmatched column)
Output should be all the rows (row 1, row 2, row 3)
Please help me out to solve the problem.
Thanks in advance.
Please try the below one.
SELECT col1, col2
FROM yourTable
where ( not exists (Select col2
FROM yourTable where col2 like 'xxx#gmail.com')
or col2 like 'xxx#gmail.com');
We can try using a union here:
SELECT col1, col2
FROM yourTable
WHERE col2 REGEXP '[[:<:]]ram#gmail.com[[:>:]]'
UNION ALL
SELECT col1, col2
FROM yourTable
WHERE col2 NOT REGEXP '[[:<:]]ram#gmail.com[[:>:]]' AND
NOT EXISTS (SELECT 1 FROM yourTable WHERE col2 REGEXP '[[:<:]]ram#gmail.com[[:>:]]');
Demo
The above strategy is that the first half of the union returns the matching record, if it exists. The second half of the union then returns all other records, but only if on match were found in the first half of the union. If a match were found, then the WHERE clause in the second half of the union would fail, and would return nothing.
Also, please note that storing comma separated (or semicolon separated) data in your MySQL tables is generally bad practice. I had to use REGEXP to get around this problem, but ideally if each email had a separate row, we would only need to use = equality.

mysql, how to give priority to a cell with a particular value

In a give table I want to select the row with the maximum value in column-A, but in the same time if there are 2 or more rows that have a maximum value a want to get the row where the value in column-B is not null, if there is one, otherwise I just get the first row with the maximum value even if the value in Column B is null.
In summary:
first choice : Column-A maximum, Column-B Not null
in case such a row does not exist
second choice : Column-A maxim, Column-B Null
Is it possible to write a single query with this constrain or do I have to create 2 queries with some logic in between?
You can use multiple columns with ORDER BY like below
SELECT columnA,columnB
FROM YourTable
ORDER BY columnA DESC, columnB DESC
It'll order by columnA first descending order, then columnB in descending order the null will be the last choice.
add a LIMIT 1 at end of query if you just one row returned.
Below Query will do the trick
SELECT * FROM tableA where columnA=(select max(columnA) from tableA) order by columnB desc
You could use an inline view to return the maximum value of col_a, and then do a join to get all the rows that have the same col_a value, then get the maximum value of col_b from those rows.
For example:
SELECT s.col_a
, MAX(t.col_b) AS col_b
FROM ( SELECT MAX(r.col_a) AS col_a
FROM mytable r
) s
JOIN mytable t
ON t.col_a = s.col_a

sum two or more columns in mysql table but leave out the null field

How to sum two or three columns, but if any column is NULL then it should not affect the value of SUM.
As i get NULL if columns are added all together.
Here is the example of table i am trying to work on.
id col1 col2 col3 total
1 2 3 5
2 10 5 NULL
3 2 NULL NULL
This is the query i tried.
SELECT id,col1,col2,col3, (col1+col2+col3) AS Total FROM test_table;
This Query works perfectly fine if there is no NULL column, but if there is any null column then number added with null becomes null and i get null in result..
Below is the Result Screen Shot i added.
in above image i get NULL in Total column if any column in sum has null.
But results should be like 10,15,2 respected to there id's.
One way would be to use IFNULL function:
SELECT id,col1,col2,col3, (IFNULL(col1,0)+IFNULL(col2,0)+IFNULL(col3,0)) AS Total
FROM test_table;
Use coalesce to replace null values with 0. I prefer coalesce. In my experience it is database agnostic, where as isnull, ifnull, nvl and others are specific to the database.
SELECT col1,col2,col3, (coalesce(col1,0)+ coalesce(col2,0)+ coalesce(col3,0)) as total from test_table;
In this case you would need to use IsNull(Column, 0) to ensure it is always 0 at minimum.
SELECT col1, col2, col3, sum(isnull(col1,0) + isnull(col2,0) + isnull(col3,0)) AS Total FROM test_table group by id;
Modify your select statement to exclude nulls.

SQL select first found value in 'in group'

Is is possible to select the first row matched in a list?
Table bar:
Column 'bar'
Values: value2, value3
SELECT * FROM `foo` WHERE `bar` IN ('value','value2','value3');
It select value2 and returns.
Thanks in advance
EDIT:
The values I am expecting are:
Foo
Foobar
Foobarsome
Foobarsomething
I determine this based on the length of the strings but I also need a default value if nothing is found. Lets say 'nothing' but nothing is bigger then foobar and could be a valid value.
You can query:
SELECT * FROM `foo` WHERE `bar` IN ('value','value2','value3') LIMIT 1;
But without additional ordering it's not deterministic, which first row will be your result.
You can use a CASE statement in the ORDER BY clause to specify the order based on column values. Then use can use LIMIT to select just one row in the result.
SELECT * FROM foo
WHERE bar IN ('value','value1','value2')
ORDER BY CASE bar WHEN 'value' THEN 1 WHEN 'value1' THEN 2 WHEN 'value2' THEN 3 ELSE 100 END
LIMIT 1;
I tested this example on SQL Fiddle.
UPDATE: The original poster edited the question and added that he wants to sort on string length and have a default value of 'nothing' returned if there are no results.
SELECT * FROM foo
WHERE bar IN ('value','value1','value2')
ORDER by CASE bar WHEN 'value' THEN 1 WHEN 'value1' THEN 2 WHEN 'value2' THEN 3 ELSE 100 END
LIMIT 1;
SELECT bar FROM
(
SELECT bar, 0 as SortOrder FROM foo
WHERE bar IN ('value','value1','value2')
UNION
SELECT 'nothing' as bar, 999 as SortOrder
) as x
ORDER BY SortOrder, LENGTH(bar)
LIMIT 1;
You can see the update query run in SQL Fiddler.
This solution works by using a UNION to combine the default value of 'nothing' to the result and also includes a "SortOrder" column. The UNION'ed queries are Order By the SortOrder column so that the default value is sorted to the bottom of the results, then the results are sorted by the length of bar. Finally there is LIMIT 1 clause so the default value 'nothing' appear in the final result if it is the only record otherwise the shortest string that matches in the 'in group' set is returned.
Mysql should work with..
SELECT *
FROM foo WHERE bar IN ('value','value2','value3')
LIMIT 0,1;
Could you please write your expected output? It will make it easier...

How to return NULL when result is empty?

I have a simple query that selects one field and only one row, thus one value.
Is there any way to make it return NULL if the query results in an empty set? Instead of returning zero rows?
I think I need to use something with NOT EXISTS, THEN NULL but not certain about it.
select
(Your entire current Select statement goes here) as Alias
from
dual
dual is a built in table with a single row that can be used for purposes like this. In Oracle this is mandatory. MySQL supports it, but you can also just select a single value without specifying a table, like so:
select
(Your entire current Select statement goes here) as Alias
In either case you're selecting a single value. This means that:
If your select returns one value, that value is returned.
If your select statement returns one column, but no rows, NULL will be returned.
If your select statement returns multiple columns and/or multiple rows, this won't work and the query fails.
An easy way to do this is with aggregation:
select max(col)
from t
where <your condition here>
This always returns one row. If there is no match, it returns NULL.
Late reply but I think this is the easiest method:
SELECT
IFNULL((SELECT your query), NULL)
Use a UNION with a NOT EXISTS(original where clause)
select col1
from mytable
where <some condition>
union
select null
where not exists (
select * from mytable
where <some condition>)
You can use COALESCE for example:
SELECT COALESCE(Field1,NULL) AS Field1 FROM Table1
Edit 1:
sorry i mistake with return field as null not result set,for result set return as null use Union and Exist Function like this:
SELECT NULL AS Field1 FROM Table1 WHERE not EXISTS(SELECT Field1 FROM Table1 WHERE Field2>0)
UNION
SELECT Field1 FROM Table1 WHERE Field2>0