Using Max in LINQ to SQL - linq-to-sql

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);

Related

MySQL Select groups of records based on change in value by comparing to previous group

Given the table, I am trying to select groups of records and sum the last column Class in each group. The rules of the grouping are slightly complicated and rows need to be compared to each other.
|| Seq || Time || Spec || Class
|| 1 || 8:05 || 0 || 5
|| 2 || 8:06 || 1 || 5
|| 3 || 8:07 || 2 ||10
|| 4 || 8:08 || 4 ||10
|| 5 || 8:09 || 3 || 5
|| 6 || 8:10 || 2 || 5
|| 7 || 8:11 || 6 || 5
|| 8 || 8:12 || 6 ||15
I need to group records based on the change in value (increase or decrease) in the Spec column. The required change in value is 2. So starting with row 1, the Spec is 0. It doesn’t increase by at least 2 until row 3. This is a valid group and I need to sum the Class field. The expected output is StartTime, StartSpec, EndTime, EndSpec, and TotalClass.
To determine the next group, I need to measure the change in value with the last row used in the previous group. As you can see, row 4 has immediately increased by 2 and so this one row is a valid group.
Expected Output:
||StartTime || StartSpec || EndTime || EndSpec || TotalClass
|| 8:05 || 0 || 8:07 || 2 || 20
|| 8:08 || 4 || 8:08 || 4 || 10
|| 8:09 || 3 || 8:10 || 2 || 10
|| 8:11 || 6 || 8:11 || 6 || 5
Can be done by using some intermediate variables, to detect the first and the last row in a group, as illustrated below.
Note that this will "auto-close" the last group, if it is not closed yet.
Also note, that for the use-cases like that, application-level solution
might be a more elegant option (as noted in the comments already).
Another option is to compute an explicit group discriminator (i.e. "gid"), at the data insertion time, and store it in the table itself, so that you can then query data in a standard way, w/o relying on any variables.
SELECT
MAX(startTime) as startTime,
MAX(startSpec) as startSpec,
MAX(endTime) as endTime,
MAX(endSpec) as endSpec,
SUM(class) as totalClass
FROM (
SELECT
/* Detect first and last rows in a group (when ordered by "seq") */
#first as isFirst,
#last:=(ABS(#prev-spec)>1 OR seq=(SELECT MAX(seq) FROM groups)) as isLast,
/* If this is a first row, set "startTime" and "startSpec" */
IF(#first,time,NULL) as startTime,
IF(#first,spec,NULL) as startSpec,
/* If this is a last row, set "endTime" and "endSpec" */
IF(#last,time,NULL) as endTime,
IF(#last,spec,NULL) as endSpec,
/* Start the next group */
IF(#last,#prev:=spec,NULL) as nextPrev,
IF(#last,(#gid:=#gid+1)-1,#gid) as gid,
/* Flip "first" */
#first:=#last as nextIsFirst,
/* Row "class" */
class
FROM
/* Declare some variables */
(SELECT #first:=TRUE,#last:=FALSE,#prev:=0,#gid:=0) init
CROSS JOIN Groups ORDER BY seq
) labeled GROUP BY gid;

How to compute one column based off multiple tables in mysql

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

Why exactly the output of this expression return true

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.

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;

Boolean Logic with If case

There are 2 cases given in the question and on that basis we have to answer.
Cases:
if((NOT(value>=1) OR NOT(value<=10))
if((NOT(value>=1) AND NOT(value<=10))
Now the questions are:
which case you are going to use if the given value either is 1 or 10 ?
which case you are going to use if the given value must be 1 or 10 ?
the problem is whether I takes 1 or 10 I am getting same answer in both the cases. That is if(0) and thus if statement is false in both the cases.?
(NOT(value>=1) OR NOT(value<=10)) = (value < 1) OR (value > 10)
This case is true for [-Infinity ... 0] or [11 ... + Infinity]
Is false for 1 or 10
((NOT(value>=1) AND NOT(value<=10)) = (value < 1) AND (value > 10)
This case is always false, as no number can be smaller than 1 and bigger than 10 the same time.