Counting Date Columns in Rails - mysql

I'm getting stuck on how to count a date. I have 3 different columns:
demodate1, demodate2, demodate3
If demodate1 exists I want to count it as 1, if demodate 2 exists, I want to count it as 1, if demodate3 exists I want to count it as 1. If more than 1 of those exist I want to add them all together.
How can I do this?
Here's my try at the code:
def demosheld
if demodate1.present? or demodate2.present? or demodate3.present?
demodate1.count + demodate2.count + demodate3.count
end
end

def demosheld
count = 0
count = count + (demodate1.present? ? 1 : 0)
count = count + (demodate2.present? ? 1 : 0)
count = count + (demodate3.present? ? 1 : 0)
end
Edit:
Other options are
[demodate1, demodate2, demodate3].inject{|sum,date| sum + date.present? ? 1 : 0 }
sum = 0
[demodate1, demodate2, demodate3].each { |date| sum += date.present? ? 1 : 0 }

How about some inject magic?
def demosheld
[demodate1, demodate2, demodate3].inject(0) do |sum, date|
sum + (date.present? ? 1 : 0)
end
end

Related

SQL statement equivalent to ternary operator

I would like to create a statement that is equivalent to (x - y == 0) ? return 0 : return 100 in MySQL. Something that might look like this:
SELECT id, [(integer_val - 10 == 0) ? 0 : 100] AS new_val FROM my_table
I want to compare an attribute in each row to a certain number, and if the difference between that number and the number in the row is 0, I want it to give me 0, otherwise, I want it to give me 100.
Example:
Applying this query on my_table (with 10 being the 'compared to' number):
id | integer_val
===================
1 10
2 10
3 3
4 9
Would return this:
id | new_val
===================
1 100
2 100
3 0
4 0
How can I do this?
Try this:
SELECT id, IF(integer_val = 10, 100, 0) AS new_val
FROM my_table;
OR
SELECT id, (CASE WHEN integer_val = 10 THEN 100 ELSE 0 END) AS new_val
FROM my_table;
Use case when statement:
select *, (case when integer_val = 10 then 100 else 0 end) as New_Val
from yourtable
Try using the IF function:
SELECT id, IF(integer_val - 10 = 0, 0, 100) AS new_val FROM my_table
(I stuck with your condition expression, but it can be simplified a bit since integer_value - 10 = 0 has exactly the same truth value as integer_value = 10.)
Note that the IF function is different from MySQL's IF statement used for stored programs.

If two columns are 1 then make new column

i need a my sql statement which selects something similar to this
SELECT present, wholeday, attendance
present and wholeday is given, while attendance is generated by a combination of present and wholeday
if present == 1 and wholeday == 1 then attendance = 1
if present == 1 and wholeday == 0 then attendance = .5
if present == 0 and wholeday == 0 then attendance = 0
Your query would be:
SELECT PRESENT, WHOLEDAY,
CASE
WHEN (PRESENT = 1 AND WHOLEDAY = 1) THEN 1
WHEN (PRESENT = 1 AND WHOLEDAY = 0) THEN 0.5
ELSE 0
END as ATTENDANCE
FROM MY_TABLE
Case Syntax is :
CASE
WHEN condition_1 THEN commands
WHEN condition_2 THEN commands
...
ELSE commands
END CASE;

Calculate average of some columns, not counting null values

I have a table with some readings that looks like this:
id foo bar baz qux
1 2 4 NULL 3
2 6 11 0 2
I want to calculate an average of some columns, not including null values in the count. Something like this pseudo-code:
select (foo+bar+baz)/countNonNulls(foo,bar,baz) AS result
FROM readings WHERE id=1;
I.e, my expected result is (2+4)/2 = 3.
Is there a way to do this in a single SQL query?
In MySQL, you can use:
select (coalesce(foo, 0) + coalesce(bar, 0) + coalesce(baz, 0) /
((foo is not null) + (bar is not null) + (baz is not null))
) as average
Note that this assumes that at least one value is not null, to prevent division by 0.
To handle the general case, you can use case:
select (case when coalesce(foo, bar, bz) is not null
then (coalesce(foo, 0) + coalesce(bar, 0) + coalesce(baz, 0) /
((foo is not null) + (bar is not null) + (baz is not null))
)
end) as average
try the where clause: where [nameColumn] is not null

Getting a numeric value out of a string

In a table named TRY I have a column ABC which has records with value abc:30|def:g h i|j:k|l:m|n:o|p: |q: 0.25 |r:0.47|s:t u
I want to fetch the numeric value after r: The example given has value as r:0.47 But it can also have a value as 123456.012596363
I am not sure on using patindex. Can anyone please help.
Many Thanks
Try this...........
declare #abc nvarchar(100) = 'abc:30|def:g h i|j:k|l:m|n:o|p: |q: 0.25 |r:0.47|s:t u'
select
substring(substring(#abc,charindex('r:',#abc) + 2 ,len(#abc)),
1,
charindex('|',substring(#abc,charindex('r:',#abc) + 2,len(#abc))) - 1)
use this query for your table
select
substring(substring(abc,charindex('r:',abc) + 2 ,len(abc)),
1,
charindex('|',substring(abc,charindex('r:',abc) + 2,len(abc))) - 1)
from TRY
-----Final Try
select case when charindex('r:',abc) = 0 then abc else
substring(substring(abc,charindex('r:',abc) + 2 ,len(abc)),
1,
charindex('|',substring(abc,charindex('r:',abc) + 2,len(abc))) - 1) end
from TRY

Weighted rotator table design

I am having a hard time with this very simple project. Maybe it's because it's Monday, I'm not sure.
I have a table that looks like this:
id | weight | hits
------------------------------------------------
1 | 4 | 0
2 | 1 | 0
3 | 2 | 0
Obviously, the hits column will increment by 1 each time that particular record is selected (We will run this update from within our PHP script).
How can I best retrieve these records by their weight? What I mean is that if I ran my query 15 times, I would want the following IDs returned:
1
1
1
1
3
3
2
1
1
1
1
3
3
2
1
We have a simple formula in place that we got online that retrieves a random weighted result, but we aren't running the formula enough to statistically balance out the results, so instead we need to do a simple rotation as described above.
I know that this is a simple problem to solve, but I'm having a hard time coming up with the best way to do it today.
I hope I've been clear enough in my description of the problem.
Unless I'm missing something (it is Monday here too after all), can't you just sort by hits / weight and LIMIT 1?
Run:
SELECT id FROM tbl WHERE weight - hits > 0 ORDER BY weight DESC LIMIT 0,1
With the last result, run:
UPDATE tbl SET hits = hits + 1, total_hits = total_hits + 1 WHERE id = (THE RESULT);
Then run
SELECT (Sum(weight-hits)) FROM tbl
If result = 0
UPDATE tbl SET hits = 0
EDIT:
It's possible to make it with two queries:
$query="SELECT id FROM tbl, weight - hits AS diff WHERE weight - hits > 0 ORDER BY weight DESC";
$result=mysql_query($query);
$num=mysql_numrows($result);
$i=0;
$id=mysql_result($result,$i,"id");
$diff =0;
while ($i < $num) {
$diff= $diff + mysql_result($result,$i,"diff");
++$i;
}
if( $diff = 1 and $i = 1);
$query2="UPDATE tbl SET hits = 0, total_hits = total_hits + IF(id='$id',1,0)";
else{
$query2="UPDATE tbl SET hits = hits + 1, total_hits = total_hits + 1 WHERE id = '$id'";
}
mysql_query($query2);