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...
Related
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
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
I am having table "business" as bellow
I want to fetch the record order by type in custom order. So I wrote the query like
SELECT * FROM business
ORDER BY FIELD (type, 'type3', 'type2', 'type10')
but what happen is other types comes up in order and the given order becomes at last. The given order should be at top and then other records. Above query returns the result as bellow.
How to bring the type3, type2 and type10 at top in order.
So that will be:
SELECT
*
FROM
business
ORDER BY
`type` IN ('type3', 'type2', 'type10'),
FIELD (`type`, 'type3', 'type2', 'type10')
Try below:
ORDER BY
CASE `type`
WHEN 'type3' THEN 1
WHEN 'type2' THEN 2
WHEN 'type10' THEN 3
ELSE 4
END
To see the selective data in top of the result set using field function you have to use either ASC or DESC on these set of values. Else the default result will be returned. Yours is an example of it.
You can try with
ORDER BY FIELD (type, 'type3', 'type2', 'type10') DESC
to see the results as
type10
type2
type3
How to bring the type3, type2 and type10 at top in order
Using ASC will result
type3
type2
type10
The input order of data to the function Field is the priority for display when used with ASC or DESC. Else the result would be default.
These fields I do not have given in query
They sure will be in resultset unless you specify a WHERE condition. FIELD function is not an alias to WHERE clause.
Refer to:
Ordering by specific field values with MySQL
MySQL: Sorting Rows
I need a query in which it starts off by selecting the entire table, then there would be a few more querys that would remove entries from the first query. Ive accomplished this by using several querys and then comparing the results in my application. I was wondering if I can accomplish this in a single query.
Algorithm
Select All AccountIDs from table
Select AccountIDs from table where parameter1 = true
Remove those matches from the original query result
Select AccountIDs from table where parameter2 = true
Remove those matches from the remaining query result
and so on up to N parameters.
This would need to also be compatible with both mySQL and SQLite
I think you are looking for this:
SELECT AccountID FROM the_table
LEFT JOIN (
SELECT AccountID FROM the_table
WHERE
parameter1 = true OR
... OR
parameterN = true ;
) AS not_included USING (AccountID)
WHERE not_included.AccountID IS NULL -- only items with no match in the "not_included" sub-query
The not_included subquery returns all items for which any parameter is set to TRUE. You actually want to exclude these records from your final result set.
Then LEFT-JOIN the_table (i.e. all items) to this sub-result. The WHERE...IS NULL clause excludes items present in the_table but not present in not_included.
Therefore only items which you do not want to exclude remain in the final result set.
The most direct way to implement your algorithm is to use a compound SELECT statement:
SELECT AccountID FROM MyTable
EXCEPT
SELECT AccountID FROM MyTable WHERE parameter1 = 1
EXCEPT
SELECT AccountID FROM MyTable WHERE parameter2 = 1
However, this is also possible with a single WHERE expression:
SELECT AccountID
FROM MyTable
WHERE NOT (parameter1 = 1 OR
parameter2 = 1 OR
...)
if I run a SELECT query that returns 10 rows, is there a way to select the 2nd item in the result set right in the SELECT statement (effectively getting a single row result)?
psedudo code:
SELECT id from MYTABLE where MYTABLE.foo = 0 and RESULT_INDEX = 2;
this would return the 2nd item from a multi item result set.
SELECT id from MYTABLE where MYTABLE.foo = 0 LIMIT 1, 1;
You'll probably want to specify an ORDER BY clause or else the nth result will be arbitrarily defined.
Edit: Oops, the first LIMIT param is zero based