SQL - Order By "Custom Preference List" - mysql

Scenario:
I have a column in a MySql table:
my_column - [INT] (Unsigned)
What I need:
I need a query to select ONE ENTRY with conditions as follows:
Given A=n
SELECT FIRST the one with my_column = n
ELSE (my_column = n null result)
SELECT the one with my_column = 0
ELSE
SELECT the one with my_column = whatever
ELSE
Return 0 entries
What I looked into:
I tried:
... WHEREmy_columnIN (n,0) ORDER BYmy_columnDESC LIMIT 1
Which applies for the first two steps, but not for the third one.
Thanks for reading.

Given your description, just use case:
order by (case when field = n then 1
when field = 0 then 2
else 3
end)
Then, of course, you would add limit 1.

Related

mysql select counts by if else condition

i have a table named cq500_all(to record diffrent doctor feedback)
now i want know counts when condition status is
field dr_1_finish and field dr_2_finish value is all fill 1
and
when field dr_1 different dr_2 (like dr_1=1 and dr_2=0,or dr_1=0 and dr_2=1 )
cause i want to know two doctors feedback counts (when different doctor's feedback on jpg)
for example image show CQ500-CT-1_36_08.jpg and CQ500-CT-1_36_09.jpg is match my select counts
it will be two (select counts result)
how to make the query on mysql?
You can count as
select count(*) as total
from cq500_all
where dr_1_finish = 1 and dr_2_finish = 1 and dr_1 != dr_2
You will got result in total
Pretty much just the way you've described it:
select *
from cq500_all
where dr_1_finish = 1 and dr_2_finish = 1
and dr_1 != dr_2
or (if dr_1 or dr_2 might not be just 0 and 1):
select *
from cq500_all
where dr_1_finish = 1 and dr_2_finish = 1
and ((dr_1 = 1 and dr_2 = 0) or (dr_1 = 0 and dr_2 = 1))

SQL where particular column values appears

I wasn't sure how to really search for this..
Lets say I have a simple table like this
ID Type
1 0
1 1
2 1
3 0
4 0
4 1
How could I select all ID's which have a type of both 0 and 1?
SELECT id,type
FROM t
GROUP BY id
HAVING SUM(type=0)>0
AND SUM(type=1)>0
You just group by id ,than with HAVING you use post aggregation filtering to check for 0 and 1.
Having is pretty expensive and that query can't hit keys.
SELECT ID FROM foo AS foo0 JOIN foo AS foo1 USING (ID) WHERE foo0.Type=0 AND foo1.Type=1 GROUP BY foo0.id.
A more generalized way of doing this would by to use a CASE column for each value you need to test combined with a GROUP BY on the id column. This means that if you have n conditions to test for, you would have a column indicating if each condition is met for a given id. Then the HAVING condition becomes trivial and you can use it like any multi-column filter, or use the grouping as your subquery and the code looks simpler and the logic becomes even easier to follow.
SELECT id, Type0,Type1
FROM (
SELECT id,
Type0 = max(CASE WHEN type = 0 THEN TRUE END)
, Type1 = max(CASE WHEN type = 1 THEN TRUE END)
FROM t
GROUP BY id
) pivot
WHERE Type0 = TRUE and Type1 = TRUE

mySQL count occurances of value on multiple fields. How?

I have a table with 5 fields. Each field can store a number from 1 - 59.
Similar to countif in Excel, how do I count the number of times a number from 1 - 59 shows up in all 5 fields?
Here's an example for the count of occurances for the number 1 in all five fields:
SELECT SUM(pick_1 = 1 OR pick_2 = 1 OR pick_3 = 1 OR pick_4 = 1 OR pick_5 = 1) AS total_count_1
FROM tbldraw
Hopefully I made sense.
There was an answer here that had a solution. I think this is just a variation.
Step1: Create a numbers table (1 field, called id, 59 records (values 1 -59))
Step2:
SELECT numbers_table.number as number
, COUNT(tbldraw.pk_record)
FROM numbers_table
LEFT JOIN tbldraw
ON numbers_table.number = tbldraw.pick_1
OR numbers_table.number = tbldraw.pick_2
OR numbers_table.number = tbldraw.pick_3
OR numbers_table.number = tbldraw.pick_4
OR numbers_table.number = tbldraw.pick_5
GROUP BY number
ORDER BY number
How about a two step process? Assuming a table called summary_table ( int id, int ttl), for each number you care about...
insert into summary_table values (1,
(select count(*)
from table
where field1 = 1 or field2 = 1 or field3 = 1 or field4 = 1 or field5 = 1))
do that 59 times, once for each value. You can use a loop in most cases. Then you can select from the summary_table
select *
from summary_table
order by id
That will do it. I leave the coversion of this SQL into a stored procedure for those that know what database is in use.
The ALL() function, which returns true if the preceding operator is true for all parameters, makes the query particularly elegant and succinct.
To find the count a particular number (eg 3):
select count(*)
from tbldraw
where 3 = all (pick_1, pick_2, pick_3, pick_4, pick_5)
To find the count of all such numbers:
select pick_1, count(*)
from tbldraw
where pick_1 = all (pick_2, pick_3, pick_4, pick_5)
group by pick_1

Counting total and true condition lines

How to count the number of lines in a table and the number of lines where a certain condition is true without resorting to subselects like this:
create table t (a integer);
insert into t (a) values (1), (2), (null);
select
(select count(*) from t) as total_lines,
(select count(*) from t where a = 1) as condition_true
;
total_lines | condition_true
-------------+----------------
3 | 1
select count(*) as total_lines, count(a = 1 or null) as condition_true
from t
;
total_lines | condition_true
-------------+----------------
3 | 1
It works because:
First while count(*) counts all lines regardless of anything, count(my_column) will count only those lines where my_column is not null:
select count(a) as total
from t
;
total
-------
2
Second (false or null) returns null so whenever my condition is not met it will return null and will not be counted by count(condition or null) which only counts not nulls.
Use SUM(condition)!
select
count(*) as total_lines,
sum(a = 1) as condition_true
from t
See it working here.
This works because in mysql, true is 1 and false is 0, so the sum() of a condition will add 1 when it's true and 0 when it's false - which effectively counts the number of times the condition is true.
Many people falsely believe you need a case statement, but you don't with mysql (you do with some other databases)
this can be easily done using a condition inside count. I don't know if its the optimized method of doing it but it gets the work done
you can do it as follows
select count(*) as total_lines, COUNT(CASE WHEN a = 1 THEN 1 END) as condition_true from t
you can check it here
sqlFiddle

Comparing 2 Columns in same table

I need to compare 2 columns in a table and give 3 things:
Count of rows checked (Total Rows that were checked)
Count of rows matching (Rows in which the 2 columns matched)
Count of rows different (Rows in which the 2 columns differed)
I've been able to get just rows matching using a join on itself, but I'm unsure how to get the others all at once. The importance of getting all of the information at the same time is because this is a very active table and the data changes with great frequency.
I cannot post the table schema as there is a lot of data in it that is irrelevant to this issue. The columns in question are both int(11) unsigned NOT NULL DEFAULT '0'. For purposes of this, I'll call them mask and mask_alt.
select
count(*) as rows_checked,
sum(col = col2) as rows_matching,
sum(col != col2) as rows_different
from table
Note the elegant use of sum(condition).
This works because in mysql true is 1 and false is 0. Summing these counts the number of times the condition is true. It's much more elegant than case when condition then 1 else 0 end, which is the SQL equivalent of coding if (condition) return true else return false; instead of simply return condition;.
Assuming you mean you want to count the rows where col1 is or is not equal to col2, you can use an aggregate SUM() coupled with CASE:
SELECT
COUNT(*) AS total,
SUM(CASE WHEN col = col2 THEN 1 ELSE 0 END )AS matching,
SUM(CASE WHEN col <> col2 THEN 1 ELSE 0 END) AS non_matching
FROM table
It may be more efficient to get the total COUNT(*) in a subquery though, and use that value to subtract the matching to get the non-matching, if the above is not performant enough.
SELECT
total,
matching,
total - matching AS non_matching
FROM
(
SELECT
COUNT(*) AS total,
SUM(CASE WHEN col = col2 THEN 1 ELSE 0 END )AS matching
FROM table
) sumtbl