If we have a table of 15 columns, the first one is id, and the other columns have numeric
data type,
in MySQL or a similar languages, how can I find if the record have 7 consecutive non zero values, meaning that 7 of the contiguous columns have a value not equals to zero?
We can write a query has a lot of OR operations to check that each 7 columns don't have 0 value, but I want to know if there is shorter way
Try the following using CONCAT and INSTR functions, explanation is within query comments:
/*
check if the col value is not equal to 0,
this will return 1 if true and 0 if false,
and concatenate all of the returned values.
*/
with concat_cols as
(
select *,
concat(
col1<>0, col2<>0, col3<>0, col4<>0, col5<>0,
col6<>0, col7<>0, col8<>0, col9<>0, col10<>0,
col11<>0, col12<>0, col13<>0, col14<>0, col15<>0
) as con_col
from table_name
)
/*
using the instr function, check if the concatenated
result contains 7 consecutive 1s (7 not 0 values).
*/
select * from concat_cols
where instr(con_col, repeat('1', 7))
See demo
One way:
field(0,col1,col2,col3,col4,col5,col6,col7) = 0 or
field(0,col2,col3,col4,col5,col6,col7,col8) = 0 or
field(0,col3,col4,col5,col6,col7,col8,col9) = 0 or
field(0,col4,col5,col6,col7,col8,col9,col10) = 0 or
field(0,col5,col6,col7,col8,col9,col10,col11) = 0 or
field(0,col6,col7,col8,col9,col10,col11,col12) = 0 or
field(0,col7,col8,col9,col10,col11,col12,col13) = 0 or
field(0,col8,col9,col10,col11,col12,col13,col14) = 0 or
field(0,col9,col10,col11,col12,col13,col14,col15) = 0
SELECT id
FROM your_table
WHERE SUM(CASE WHEN column_2 > 0 THEN 1 ELSE 0 END +
CASE WHEN column_3 > 0 THEN 1 ELSE 0 END +
CASE WHEN column_4 > 0 THEN 1 ELSE 0 END +
CASE WHEN column_5 > 0 THEN 1 ELSE 0 END +
CASE WHEN column_6 > 0 THEN 1 ELSE 0 END +
CASE WHEN column_7 > 0 THEN 1 ELSE 0 END +
CASE WHEN column_8 > 0 THEN 1 ELSE 0 END) >= 7
sql import file
--sources (id, name)---
1, "source one"
2, "source two"
3, "source three"
--first_related_items (value, source_id) ---
0, 1
--second_related_items (value, source_id) ---
0, 2
2, 3
--third_related_items (value, source_id) ---
1, 3
I have source rows and related items in multiple other tables. How do I get a computed column based off the other tables? The computed column would be for each row in source table. Like
SELECT
sources.name as name,
COMPUTED_VALUE(
first_related_items,
second_related_items,
third_related_items) as result
FROM sources
The computed column would be derived something like this
if(value for source row in first table == 0){
return 0
}
else if(value for source row in second table == 0){
if(value for source row in third table == 1){
return 1
} else {
return 0
}
} else if(value for source row in third table != NULL){
return value for source row in third table
} else {
return -1
}
You can join all four tables and compute this column as a case expression:
SELECT s.id,
CASE WHEN fri.value = 0 THEN 0
WHEN sri.value = 0 THEN CASE WHEN tri = 1 THEN 1 ELSE 0 END
WHEN tri IS NOT NULL THEN tri
ELSE -1
END AS computed_value
FROM sources s
LEFT JOIN first_related_items fri ON fri.source_id = s.id
LEFT JOIN second_related_items sri ON sri.source_id = s.id
LEFT JOIN third_related_items tri ON tri.source_id = s.id
I have this expression:
!(1 && !(0 || 1))
The output returns 1 true. And that's ok. When I read the expression I came to the same conclusion before checking the output. But I would really appreciate if someone can explain to me why the returning value is true, that way, I will have a better understanding of boolean logic and how to implement better evaluators in my code.
Key observation here: ! is not, && is the "And" operator, and || is the "Inclusive Or" Operator.
What are you really asking when you say "why it's true?".
0 = false
1 = true
AND && table
0 0 -> 0
0 1 -> 0
1 0 -> 0
1 1 -> 1
OR || table
0 0 -> 0
0 1 -> 1
1 0 -> 1
1 1 -> 1
NOT ! table
0 -> 1
1 -> 0
With parentheses implying "do this first", the statement reduces using the tables above:
!(1 && !(0 || 1))
!(1 && !1)
!(1 && 0)
!0
1
But I don't know "why" it's true. Because that's what an AND operation is, what an OR operation is, and what a NOT operation is, and how reducing a statement works. With those definitions, it can't be another answer, so it's that answer. But you already know that, because you did it yourself and got the same answer ... so what does the question mean?
The innermost expression (0 || 1) is always true.
So !(0 || 1) is always false.
That leaves 1 && 0, which is always false.
So !(false) is always true.
Please forgive my freely intermixing 0/false and 1/true.
The human evaluator (:-).
Working through the expression, following order of operation:
!(1 && !(0 || 1))
= !(1 && !(1))
= !(1 && 0)
= !(0)
= 1
Step by step explanation:
1 = true
0 = false
Starting point: !(1 && !(0 || 1))
Lets start with the inner most expression: !(0 || 1)
Var1 || Var2 =
Var1 or Var2 =
If Var1 or Var2 is 1 or both are 1, the result is 1.
(0 || 1) = 0 or 1 -> the second variable is 1 so the expression is 1.
Insert the result (0 || 1) = 1 into Startingpoint: !(1 && !(1))
! = not (inverts the value of what is behinde)
!1 = 0
!0 = 1
!(0 || 1) = !(1) = 0
Insert the result !(1) = 0 into Startingpoint: !(1 && 0)
So we have !(1 && 0)
Var1 && Var2 = And =
the opossite of or =
If Var1 AND Var2 are both 1, the result is 1. Else it is 0 =
If Var1 or Var2 is 0, the result is zero
1 && 1 = 1
1 && 0 = 0
everything else: 0
So this is left: !(0)
Reminder: ! = not = inverts the expression behind it. So !0 = 1 (and !1 = 0)
This is 1. Or in your case: true
A good book for Beginner C programmers and people who want to learn about programming and logic in an easy, understandable way:
C for Dummies by Dan Godkins
!(1 && !(0 || 1))
Since, you have used parenthesis, evaluation takes place according to them.
First, evaluate innermost parenthesis.
0 || 1 => always true.
!(0 || 1) => !(true) => always false.
1 && !(0 || 1) => 1 && false => always false.
!(1 && !(0 || 1)) => !false => always true.
From the above sample data, i want to write a query that will return SalesAmount as 0.0 if ExpRow value = 1 and return ExpenseAmount as 0.0 if ExpRow value = 2
SELECT
ExpRow,
ExpenseDate,
CASE WHEN ExpRow = 2 THEN 0 ELSE ExpenseAmount END AS ExpenseAmount,
CASE WHEN ExpRow = 1 THEN 0 ELSE SalesAmount END AS SalesAmount
FROM
Table
Not sure if this is exactly what you are after but...
SELECT CASE([ExpRow]) WHEN 1 THEN 0 ELSE SalesAmount END AS 'SalesAmount',
CASE([ExpRow]) WHEN 2 THEN 0 ELSE ExpenseAmount END AS 'ExpenseAmount'
FROM [YOUR_TABLE]
Trouble with using Max in where clause of LINQ to SQL. Data below:
QID, Question, TypeID, Disable, VersionID, Sequence
1 Who's on 1st 1 False 1 1
2 Who's on 1st 1 False 2 1
3 What's on 2nd 1 False 1 2
4 What's on 2nd 1 False 2 2
5 I don't know 1 False 1 3
6 I don't know 1 False 2 3
I need to return a group of questions based on the Max of the VersionID as noted below. The result I expect from the data above would include rows 2, 4 & 6 ordered by Sequence.
IEnumerable<QUESTION> questions =
(from q in dataContext.QUESTIONs
where q.TypeID == Convert.ToInt16(ddlType.SelectedValue)
&& (q.Disable == null || q.bDisable == false)
&& (q.VersionID == dataContext.QUESTIONs.Max(q.nVersionID))
orderby q.Sequence ascending
select q);
Max() translates properly in linq-to-sql
Try
IEnumerable<QUESTION> questions = (from q in dataContext.QUESTIONs
let maxVersion = dataContext.QUESTIONs.Max(q.nVersionID)
where q.TypeID == Convert.ToInt16(ddlType.SelectedValue)
&& (q.Disable == null || q.bDisable == false)
&& (q.VersionID == maxVersion)
orderby q.Sequence ascending
select q);