Preference for rows where field is different from "x" - mysql

I want to query my database so that I don't order by or order by desc but instead seek rows when a given field is different from 0 first and only after get others ordered by if there are no rows with field != "0". What is the best way to accomplish this or even is it possible to do so?
This is supposing the field can have values from -100 to 0 to 100
With example:
Considering LIMIT equals 3 and field in consideration is field1
field1
10
0
-20
-40
Another set:
field1
0
0
-100
50
In the first set, the results extracted will be 10, -20 and -40 (by any order), while in the second set they should be -100, 50 and 0 (any of the zeros, by any order).
First I'd like to check whether there exists != 0 in the database and if true extract those and only after 0's until I fill the LIMIT

something like this?
its not clear AT ALL what you want so I'm only guessing here.
I want to query my database so that I don't order by or order by desc but instead seek rows when a given field is different from 0
seek rows to me means find all rows that are not 0.
only after get others ordered by if there are no rows with field != "0".
to me that means order the rows in a sub query where the field is not 0.
with that in mind maybe this query?
SELECT * FROM table t
WHERE field IN (
SELECT field
from table t
WHERE field <> 0
ORDER BY field
)
without data It's not clear what you want. but i think something like this is what you were asking.. you could also try
SELECT * FROM table t
WHERE field <> 0
ORDER BY field

Related

Get least 10 values in mysql query

I have a table in mysql. Table Name is constitutive_table, it contains more than 40 columns and its type is varchar, it contains more than 25000 records. I wrote the query like this to get the 10 least value. But it showing like as you have seen in the picture.
SELECT `Sequence_Name`
, `Name_of_the_Protein`
, `Brain`
FROM `constitutive_table`
where `Brain` != 0
ORDER
BY cast(Brain AS int)
LIMIT 0,10
The data in the Brain column appears to be floating point, so you should be casting to the appropriate type:
SELECT Sequence_Name, Name_of_the_Protein, Brain
FROM constitutive_table
WHERE CAST(Brain AS DECIMAL(14, 8)) <> 0
ORDER BY CAST(Brain AS DECIMAL(14, 8))
LIMIT 10
Most likely what is happening now is that the 10 values you see all have the same value when cast to integer. As a result, MySQL is using some secondary sort to generate the order you do see.
While the above query may resolve your problem, ideally you should change the Brain column to some numeric type.

Selecting a value based on how another field was generated

I'm selecting some data;
select c.*,
coalesce(s.column1, ...),
coalesce(s.column2, ...),
FROM
(SELECT ...)
Basically, if s.column1 or s.column2 is null then I am putting in some logic to take the average of that column and use it instead.
I want to have another field so I can know weather or not that value was computing using the average or not - perhaps a boolean? Lets say the average for column1 was 120, the table would look like;
column1 column2 avg
54 10 0
200 40 0
120 180 1
499 160 0
This allows me to see that the third row was generated using the avg of all rows as it was initially null.
How could the logic for the avg column work?
Your question seems fairly moot to me because:
The AVG function ignores NULL values by default, so the average using the overall average for NULL slots is the same as leaving out those slots entirely, and
If you just want to mark the rows which had a NULL value, you can use a CASE expression
So, to get what you want, just use this:
SELECT
column1,
column2,
CASE WHEN column1 IS NULL THEN 1 ELSE 0 END AS avg
FROM yourTable;
And know that SELECT AVG(column1) FROM yourTable would return the same value whether NULL rows were omitted, or the overall average were used.

SAS : Eliminate duplicates if a condition is satisfied

I want to eliminate duplicates from a database, based on an identifier, an order and a condition.
More precisely, I have data with several observations. I have sometimes a condition that makes me want to keep that observation anyway (let fix it condition=1), but then also keep the observation with the same identifier even if this condition does not hold (condition=0).
But if I have for one identifier several observations where condition=0 then I want to elminate duplicates, with criterion being having the greatest order.
Without the condition I can do that
proc sort data=have;
by identifier descending order;
run;
proc sort nudopkey data=have;
by identifier;
run;
But how to incorporate my condition in this ?
Edit 1 : add a database example :
data Test;
input identifier $ order condition;
datalines;
1023 1 0
1023 2 0
1064 2 0
1064 1 0
1098 1 0
1098 1 1
;
Then I want to keep
1023 2 0
1064 2 0
1098 1 0
1098 1 1
Edit 2 : tried to precise my conditions
I presume you want to eliminate duplicates only when the condition for all records for an identifier is set to 0. In that case you want to keep the record with the maximum order and eliminate all other records with the same identifier.
Proc sql;
create table want as
select *
from test
group by identifier
having max (condition) ne 0
or order eq max (order)
;
Quit;
This will keep all rows for an Identifier where the maximum condition = 1,
or in the case of those where maximum condition = 0, select the row with the maximum order.
Is that what you want?
Some of this depends on how you define 'condition'. Is your condition easily verifiable on every record for that identifier? Then you can do something like this.
Evaluate the condition.
For records where it is true (you want to remove the duplicate), set flag=0. For records where it is not true, increment the condition flag by one.
If the condition is true for all records in that ID, all will have the same value (flag=0) and nodupkey on by identifier flag; will remove extras. If the condition is false for all records, those will not be removed. If it's true for some and false for some, and you want to remove only some of the records with that identifier (only the duplicates where it is true), then you have to make sure that either it's sorted to have all of the condition=true records at top, or have a separate flag counter that determines what value the flag will be (since it sometimes will go to 0 in the middle, so 0 0 0 1 2 3 0 4 5 6 is what you want, not 0 0 0 1 2 3 0 0 1 2 ).
Perhaps easier to see is to do it within a datastep. After sorting by identifier descending order:
data want;
set have;
by identifier descending order;
if (condition=true) and not (first.identifier) then delete;
run;
This will, again, work if either condition=true is always at the top, or if it's always consistent within one ID group. If it's inconsistent and mixed, then you need to keep track of whether you've kept one where it was true (assuming you want to), or it might delete all records where it is true; use a separate variable to keep track of how many you've kept. first.identifier will be 1/TRUE for the first record for that identifier only, not taking into account the condition. You could also create the flag, then sort by identifier flag descending order; and guarantee the condition=true are at the top (either by making flag=0 for true, or sorting by descending flag.)

Report and Graphic in access 2007 - calculating values on queries

Picture a table with fields (Id, Valid, Value)
Valid = boolean
Value = number from 0 to 100
What I want is a report that counts the number of records where (valid = 0), and then gives me the total number of cases where (value < 70) and the number of cases where (value >= 70).
The problem is that the "value" field could be empty on some of the records and I only want the records where the value field is not empty.
I know that the second value (value>=70) is going to be calculated, but the problem is that I can't simply do (total number of records - number of records where value < 70), because there's the problem with the records where "value" is null...
And then I want to create graphic with these values, to see the percentage of records below and above 70.
"The problem is that the "value" field could be empty on some of the records and I only want the records where the value field is not empty."
Use a WHERE clause to exclude rows whose "value" field is Null.
Here is sample data for tblMetraton.
Id Valid Valu
1 -1 2
2 0 4
3 -1 6
4 0
5 0 90
I used Valu for the field name because Value is a reserved word.
You can use the Count() function in a query and take advantage of the fact it only counts non-Null values. So use Count() with an IIf() expression which returns a non-Null value (I used 1) for the condition you want to match and Null otherwise.
SELECT
Count(IIf(Valid=0,1,Null)) AS valid_false,
Count(IIf(Valu<70,1,Null)) AS below_70,
Count(IIf([Valu]>=70,1,Null)) AS at_least70
FROM tblMetraton AS m
WHERE (((m.[Valu]) Is Not Null));
Based on my sample data in tblMetraton, that query gives me this result set.
valid_false below_70 at_least70
2 3 1
If my sample data does not address the variability you're dealing with, and/or if my query results don't match your requirements, please show us you own sample data and the results you want based on that sample.

MySQL database resultset with values as close to a number "x" as possible

Im trying to get a result set that contains the 10 values that are closest to, in this case, the number 3.
I have a database that has values in a column named rated which can be 1,2,3,4 or 5. What im trying to do is query the database and return the first 10 rows that have the values closest to 3. The values can be above 3 or below 3. I should note that these values in the rated column are floats.
I then need to sort these rows in order so that rows with value of 3 are first and then the row with lowest offset (+/-) from 3.
Is there any SQL query that can return atleast the result set of values closest to 3 ? or am i going to have to return the whole db and sort it myself?
To get the first 10 rows with highest value down i used the statement
SELECT * FROM tabs ORDER BY 5 DESC LIMIT 10";
5 refers to the column rated
Is there some way to modify this to do what i want ?
Thanks
If I understand your problem correctly, this should do the trick:
select *
from tabs
order by abs(`rated` - 3) asc
limit 10
Note that it sorts by the difference in ascending order, so those with a difference of 0 will come first.
SELECT * FROM tabs ORDER BY ABS(3 - Rate) ASC LIMIT 10
If I got right what you need try:
select *
from (
select
case when -(3-rated) > 0 then -(3-rated) else (3-rated) end as distance,
tabs.*
from tabs
) subsel
order by distance
limit 10