How to implement score points for each WHERE clause in SELECT statement - mysql

how can i create column with information about how much condition was passed for each field?
eg. I have client who find property with max price to 500000, 3th floor and living area between 45 meters. Now when i use "AND" for each condidtions i will get rows with 100% compatibility. But What abaout to find rows with the same condidtions as before but without living area in range. There will be 66% copatibility because 2/3 of my conditions is passed.
There is my sqlfiddle http://sqlfiddle.com/#!9/1ef60c/5

Simple way to solve your problem is:
SELECT *,
(
CASE WHEN `property_max-price` < 550000 THEN 1 ELSE 0 END
+
CASE WHEN property_additional LIKE "%hot_water%" THEN 1 ELSE 0 END
+
CASE WHEN `property_floor-from` >= 2 AND `property_floor-to` <=5 THEN 1 ELSE 0 END
) / 3 * 100 AS `%`
FROM client

Related

SQL query - find values that meet m conditions out of n

Is there any way to find values that meet any m conditions out of given n conditions? For instance, if there are 10 conditions, and I want to find values that meet any 2 of them.
Use CASE expressions in the WHERE clause, 1 for each condition like this:
WHERE 2 =
CASE WHEN <condition1> THEN 1 ELSE 0 END +
CASE WHEN <condition2> THEN 1 ELSE 0 END +
CASE WHEN <condition3> THEN 1 ELSE 0 END +
..........................................
You can change the = sign to > or < to meet your requirement.
There is. It's not gonna be pretty though.
Start with your conditions as SELECT expressions.
select T.*,
case
when T.SOME_NUMERIC_COLUMN > 0 then 1
else 0
end IS_POSITIVE,
(select sign(COUNT(*))
from SOME_OTHER_TABLE
where parent_id = T.ID) HAS_CHILDREN
...
from SOME_TABLE T
Design these expression in such a way that you get 1 when a condition is met and 0 when it's not.
Then sum up the score and add a WHERE clause.
SELECT *
FROM (
SELECT R.*,
IS_POSITIVE + HAS_CHILDREN + ... SCORE
FROM (...) R)
WHERE SCORE > 2
Of course you're gonna pay a hefty price in performance for this. You won't be able to use your conditions directly to limit the resultset so I'd expect the execution plans to be extremely disappointing. That said, it's not like what you have in mind is a standard task for RDBMS so it should be enough for a proof of concept.

SQL Inner Join w/ sub query to return difference w/criteria

What am I doing:
I'm attempting to take two tables, one with 2016 data and one with 2015 data, and subtract the cells in each column to display only the differences greater than or equal to 10,000, rounded to the nearest 100th place, in a new table.
The Issue:
I am able to get the new table to pop up with the correct amounts displayed for the subtraction part only. I'm not able to add any additional criteria to filter the results to display the >= 10000 or the rounding to the 100th spot.
After research it looks like my JOIN needs a subquery to display what i would like, but I've been messing around with it for hours now and I can't seem to get it to display anything when I add a sub. Any assistance would be great. Here is what I have that works without the >= 10000 and rounding:
SELECT
`prioryeardata`.location,
`currentdata`.`2010` - `prioryeardata`.`2010` AS '2010_Difference',
`currentdata`.`2011` - `prioryeardata`.`2011` AS '2011_Difference',
`currentdata`.`2012` - `prioryeardata`.`2012` AS '2012_Difference',
`currentdata`.`2013` - `prioryeardata`.`2013` AS '2013_Difference',
`currentdata`.`2014` - `prioryeardata`.`2014` AS '2014_Difference',
`currentdata`.`2015` - `prioryeardata`.`2015` AS '2015_Difference'
FROM `prioryeardata`
JOIN `currentdata`
ON `prioryeardata`.location = `currentdata`.location;
Have a look at the below query it may help (using sql-server)
select location,Round([2010_Difference],3).[2010_Difference],Round([2011_Difference],3)[2011_Difference]
,Round([2012_Difference],3)[2012_Difference],Round([2013_Difference],3)[2013_Difference]
,Round([2014_Difference],3)[2014_Difference],Round([2015_Difference],3)[2015_Difference] from
( SELECT
prioryeardata.location,
currentdata.year2010 - prioryeardata.year2010 AS [2010_Difference],
currentdata.year2011 - prioryeardata.year2011 AS [2011_Difference],
currentdata.year2012 - prioryeardata.year2012 AS [2012_Difference],
currentdata.year2013 - prioryeardata.year2013 AS [2013_Difference],
currentdata.year2014 - prioryeardata.year2014 AS [2014_Difference],
currentdata.year2015 - prioryeardata.year2015 AS [2015_Difference]
FROM prioryeardata
JOIN currentdata
ON prioryeardata.location = currentdata.location
) t where t.[2015_Difference]>=10000 --or .......
Edit
select location,Round([2010_Difference],3).[2010_Difference],Round([2011_Difference],3)[2011_Difference]
,Round([2012_Difference],3)[2012_Difference],Round([2013_Difference],3)[2013_Difference]
,Round([2014_Difference],3)[2014_Difference],Round([2015_Difference],3)[2015_Difference]
from
(select t.location
,case when [2010_Difference]>10000 then [2010_Difference] Else 0 End as [2010_Difference]
,case when [2011_Difference]>10000 then [2011_Difference] Else 0 End as [2011_Difference]
,case when [2012_Difference]>10000 then [2012_Difference] Else 0 End as [2012_Difference]
,case when [2013_Difference]>10000 then [2013_Difference] Else 0 End as [2013_Difference]
,case when [2014_Difference]>10000 then [2014_Difference] Else 0 End as [2014_Difference]
,case when [2015_Difference]>10000 then [2015_Difference] Else 0 End as [2015_Difference]
from
( SELECT
prioryeardata.location,
currentdata.year2010 - prioryeardata.year2010 AS [2010_Difference],
currentdata.year2011 - prioryeardata.year2011 AS [2011_Difference],
currentdata.year2012 - prioryeardata.year2012 AS [2012_Difference],
currentdata.year2013 - prioryeardata.year2013 AS [2013_Difference],
currentdata.year2014 - prioryeardata.year2014 AS [2014_Difference],
currentdata.year2015 - prioryeardata.year2015 AS [2015_Difference]
FROM prioryeardata
JOIN currentdata
ON prioryeardata.location = currentdata.location
) t where t.[2010_Difference]>=10000 or t.[2011_Difference]>=10000 or t.[2012_Difference]>=10000
or t.[2013_Difference]>=10000 or t.[2014_Difference]>=10000 or t.[2015_Difference]>=10000
)tt
If you want cells to show blank instead of a value, use a pattern like this under your SELECT:
CASE WHEN `currentdata`.`2015` - `prioryeardata`.`2015` >= 10000 THEN
`currentdata`.`2015` - `prioryeardata`.`2015` ELSE NULL END AS '2015_Difference'
strictly speaking the else null is unnecessary, I just put it in for your learning benefit
If you want to only show rows where the difference is greater than ten k put this in on the end of your query:
WHERE
`currentdata`.`2015` - `prioryeardata`.`2015` >= 10000
If you want to only show rows where all years were over ten k, add similar filters for other years separated by AND. If you want to show rows where any year was over ten k, separate them with OR
To round values to the nearest 100 (i.e. 12345 becomes 12300) I believe you would use
ROUND(12345,-2)

How can I multiply numbers(data) in one column in MySQL?

How can I multiply all numbers in one column?
for example:
Status(finished or not finished)
1
1
1
1
0
I know how to use sum.
sum(Status)=4
I need some thing like sum for multiply
mul(status)=0
do we have something like mul(status)?
I don't know of a multiply aggregate function. However, in the case of a column containing only zeroes and ones the product will be one only if every value be one, otherwise it will be zero:
SELECT
CASE WHEN SUM(status) = COUNT(status) THEN 1 ELSE 0 END AS product
FROM yourTable
CASE WHEN SUM(status) = COUNT(status) THEN 1 ELSE 0 END AS product

Getting Sum of milligram, grams, and kilograms in MYSQL

I use data types decimal(10,3) and now I try to get SUM of all column, and it will return depends on what is the SUM of all units.
E.g.:
0.789 mg
98.057 g
5.008 kg
The query are automatically calculate this, but how?
I've tried this:
SELECT CONCAT(SUM(prod_name,'-',prod_quantity,' ',
CASE WHEN prod_unit = 'mg' THEN 'g'
ELSE prod_unit
END)) AS shortName
FROM prod_table;
The answer is wrong, and I don't know what is the formula on adding mass or volume.
There are two parts to this question. First, you should add the weights properly, which means adding them all after converting them to the same units. To avoid losing precision, let's add them in milligrams:
SELECT SUM(prod_quantity * CASE prod_unit WHEN 'mg' THEN 1
WHEN 'g' THEN 1000
WHEN 'kg' THEN 1000000
END) sum_milligrams
FROM prod_table;
This will give the results in milligrams. Now, we can handle beautifying the output by deciding in which units to display it. For example, we could decide that anything weighing 1 kg or more would be displayed in kg, anything between 1 gr and 1 kg would be displayed in grams and anything less than that would be displayed in milligrams:
SELECT CASE WHEN s > 1000000 THEN CONCAT(s/1000000.0, ' kg')
WHEN s BETWEEN 1000 AND 1000000 THEN CONCAT(s/1000, ' g')
ELSE CONCAT(s, ' mg')
END
FROM (SELECT SUM(prod_quantity * CASE prod_unit WHEN 'mg' THEN 1
WHEN 'g' THEN 1000
WHEN 'kg' THEN 1000000
END AS s
FROM prod_table) t;

Sum function producing whole number instead of percentage

So I have a field 'total' which is made of (fin_dec+fin_acc). I've been trying to divide total by fin acc:
select sum(case when fin_acc = 0 then 0 else (total/fin_acc)end)as sum1
The case statement is because it won't divide by 0s!
For example, total is 4 and fin_acc is 3 therefore the sum should be 75% however it's just giving me 3. It could be how I've created the fin_dec, fin_acc fields as a case when... then 1 else 0 and therefore wont split into a percentage.
Any ideas?
use the nullif function:
select sum(1.0*total/nullif(fin_acc,0))as sum1
Like this:
select sum(fin_acc) as s, count(fin_acc) as n from ..
then in your programming language:
if(n>0) avg= s/n else avg= null;
or just use:
select avg(fin_acc) as a from ..