Convert SQL - LINQ - Problem with using both Min/Max - sql

Is there a online system which converts SQL - LINQ or can anyone else help convert the SQL - LINQ below?
SELECT MIN(startTime) As startTime, MAX(endTime) As endTime
FROM tblRA
LEFT JOIN tblA ON tblRA.asID = tblA.asID
WHERE 'xxxxxx' BETWEEN tblRA.startDate AND tblRA.endDate
AND tblA.availabilityDayOfWeek = 7
The main area I am having trouble is the .MAX/.MIN.
Heres what I have so far
public List<string> GetResourceAvailabilitiesByDate(DateTime searchDate)
{
DayOfWeek dayOfWeek = searchDate.DayOfWeek;
var minVal = from a in dc.tblResourceAvailabilities
join b in dc.tblAvailabilities on a.asID equals b.asID
where searchDate.Date >= a.startDate.Date && searchDate.Date <= a.endDate.Value.Date
&& b.availabilityDayOfWeek == (int)dayOfWeek
select b.startTime.ToShortTimeString();;
var maxVal = from a in dc.tblResourceAvailabilities
join b in dc.tblAvailabilities on a.asID equals b.asID
where searchDate.Date >= a.startDate.Date && searchDate.Date <= a.endDate.Value.Date
&& b.availabilityDayOfWeek == (int)dayOfWeek
select b.endTime.ToShortTimeString();
var min = minVal.Min(minVal.Min);
var max = maxVal.Max();
return min,max;
Thanks in advance for any help
Clare

I think your code is a little bit incorrect, and the first symptom of it is that you are using repeated code to define minval and maxval. I tried to simulate something similar to what you want and came to the following code, please adapt it to your needs.
public List<string> GetResourceAvailabilitiesByDate(DateTime searchDate)
{
DayOfWeek dayOfWeek = searchDate.DayOfWeek;
var vals = from a in dc.tblResourceAvailabilities
join b in dc.tblAvailabilities on a.asID equals b.asID
where searchDate.Date >= a.startDate.Date && searchDate.Date <= a.endDate.Value.Date
&& b.availabilityDayOfWeek == (int)dayOfWeek
select b;
var min = vals.Min(v => v.startTime).ToShortTimeString();
var max = vals.Max(v => v.startTime).ToShortTimeString();
return new List<string>() { min, max };
}
Some comments on your code, assuming it's C#.
You are trying to return an array of strings when you should be returning an array of dates.
Your where clause is pretty confuse. You're comparing the search date with startdate.Date and endDate.Value.Date. It does not make much sense.
Your select clause could select only b, or a, or whatever. You don't really need to select the date in it.

Related

Entity Framework Core 6 - Date Comparision

I need to create a query to find records between a date range. I need to truncate the time for comparison. I came across a few threads suggesting to truncate time using DbFunctions.TruncateTime when comparing the dates.
I cannot find DbFunctions class in EntityFrameworkCore 6.0. How do I truncate time and compare the DateTime columns?
Edit: Excerpt from my query handler
IQueryable<TestReportItem> query = _context.TestReportItems;
DateTime requestDateStart = DateTimeOffset.FromUnixTimeMilliseconds(request.TestDateStart).LocalDateTime;
DateTime requestDateEnd = DateTimeOffset.FromUnixTimeMilliseconds(request.TestDateEnd).LocalDateTime;
if (request.FacilityId != 0)
{
query = query.Where(e => e.FacilityId == request.FacilityId);
}
if (request.TestDateStart != 0 && request.TestDateEnd != 0)
{
query.Where(e => e.TestDate.Date >= requestDateStart
&& e.TestDate.Date <= requestDateEnd);
}
var count = query.Count();
return count;
The request will be for a date range (dates converted into UnixTimeMilliseconds). I am using SqLite database.

How to compare two values in different columns and different rows, related to an ID

I'm starting to learn Power BI and metrics with DAX and some help will be apreciated, please. I would need to know how, in a sorted table (by ID, Modification and Date), of data already defined by fields ([ID, Modification, Fecha(=Date), V_INICIAL, V_FINAL, RESULT]), I can compare values ​​of different rows and columns, regardless of the number of iterations. My objective is to calculate a measure that returns the Number of different IDs per type of Modification, which meet the "OK" Result. This result compares, for each value of the Modification field, the value of the V_INITIAL of the first iteration, with the value of the V_FINAL of the last iteration, of the Modification. And if both values ​​are different, the Result is "OK", since the modification has been made. Otherwise it is "NOT_OK" because there is no modification. Thank you very much for help! ;)Table
This calculated column works with your example data (where [Mod] is the [Modificación]-column):
N.B. This is by no means an optimised code. I tried to keep it as simple and easy to understand as possible.
Resultado =
var current_ID = [ID]
var current_mod = [Mod]
var maxDate =
CALCULATE(
MAX('DataTable'[Fecha]);
FILTER(
ALL('DataTable');
'DataTable'[ID] = current_ID && 'DataTable'[Mod] = current_mod
)
)
var minDate =
CALCULATE(
MIN('DataTable'[Fecha]);
FILTER(
ALL('DataTable');
'DataTable'[ID] = current_ID && 'DataTable'[Mod] = current_mod
)
)
var initialState =
CALCULATE(
MAX('DataTable'[v_inicial]);
FILTER(
ALL('DataTable');
'DataTable'[Fecha] = minDate && 'DataTable'[ID] = current_ID && 'DataTable'[Mod] = current_mod
)
)
var finalState =
CALCULATE(
MAX('DataTable'[v_final]);
FILTER(
ALL('DataTable');
'DataTable'[Fecha] = maxDate && 'DataTable'[ID] = current_ID && 'DataTable'[Mod] = current_mod
)
)
return
SWITCH(
TRUE();
[Fecha] = maxDate && initialState <> finalState; "OK";
[Fecha] = maxDate; "Not_OK";
BLANK()
)

How to group overlapping data in SQL

I have data in following fashion
Prog_Id Low_latency Max_Latency
a 1 4
a -1 5
a 3 8
a 11 12
a 12 15
Now I wish to see output as
Prog_Id Low_latency Max_Latency
a -1 8
a 11 15
Basically I wish to merge overlapping data. Can anyone help me with the code. I can manage time at the place of latency, if there is a solution with OVERLAPS clause.
Thanks
Rishabh
My initial answer was not always working. Now it looks like it is:
select distinct *
from (
select
t1.Prog_ID,
min(least(l, Low_latency)),
max(greatest(g, Max_Latency))
from yourtable t1 inner join (select
t1.Prog_ID,
least(t1.Low_latency, t2.Low_latency) l,
greatest(t1.Max_Latency, t2.Max_Latency) g
from
yourtable t1 inner join yourtable t2
on t1.Prog_ID=t2.Prog_ID
and t1.Low_latency<=t2.Max_Latency
and t1.Max_Latency>=t2.Low_Latency) t2
on t1.Prog_ID=t2.Prog_ID
and t1.Low_latency<=t2.g
and t1.Max_Latency>=t2.l
group by t1.Low_latency, t1.Max_latency) s
please see here. It's MySql code but can be converted for other DBMS.
It depends on which databse server (DBMS) you use. But there is no easy solution for. There could be a possibility to use Stored procedures . But I would prefer to do this in a programming language (which language do you use?)
After testing some around with querys of other people, I found no way in SQL.
Here is something simular to map reduce in java
public class YourData {
Double Low_latency;
Dobule Max_Latency;
int Prog_Id;
// add getter and setter here
public boolean tesetOverlapping(YourData data) {
if ((this.Low_latency<=data.Low_latency && data.Low_latency<=t1.Max_Latency) ¦¦ (this.Low_latency<=data.Max_Latency && data.Max_Latency<=this.Max_Latency)) {
this.Low_latency = Math.min(this.Low_latency, data.Low_latency);
this.Max_Latency = Math.min(this.Max_Latency, data.Max_Latency);
return true
}
return false;
}
}
String sql = "
SELECT
t1.Prog_Id,
t1.Low_latency,
t1.Max_Latency
FROM yourtable t1"
ArrayList<ArrayList<Double>> values = new ArrayList<ArrayList<Double>>();
while (row = get sql rows) {
int progIndex = values.indexOf(row.Prog_Id);
if (progIndex == -1) {
progIndex = values.indexOf(row.Prog_Id);
values.add(progIndex, new ArrayList<Double>());
}
values[progIndex].add(new YourData(row));
}
boolean foundOverlapping = false;
for (int progIndex = 0; progIndex < values.size(); progIndex++) {
// Do map reduce for each progIndex
do {
foundOverlapping = false;
for (int i = 0; i < values[progIndex].size(); i++) {
if (!values[progIndex].contains(i)) {
continue;
}
YourData cur = values[progIndex][i];
for (int x = 0; x < values[progIndex].size(); x++) {
if (i != x && values[progIndex].contains(x)) {
if (cur.tesetOverlapping(values[progIndex][x])) {
foundOverlapping = true;
values[progIndex].remove(x);
}
}
}
}
} while (foundOverlapping == true);
}
Assuming you want to group in a -infinity...9, 10...19, 20...29 pattern for the lower latency, you would need something like
SELECT
Prog_Id,
MIN(Low_latency) AS Low_latency,
MAX(Max_Latency) AS Max_Latency
FROM
your_table_name
GROUP BY
Prog_Id,
IF(FLOOR(Low_latency/10)<0,0,FLOOR(Low_latency/10))
Obviously the last line will depend on the RDBMS used, but should be quite similar among most.
You might also want to add an ORDER BY clause.

SQL date comparison in WHERE clause, TypoScript

I want to compare dates in a TypoScript select.
Here's what I have (note that I commented the were clauses) :
lib.my_val = CONTENT
lib.my_val {
select {
pidInList = 100000
max = 1
#where = effective_date < CURDATE()
#where = TIMESTAMP(effective_date) < NOW()
orderBy = effective_date DESC
}
table = tx_my_table
renderObj = COA
renderObj {
5 = TEXT
5{
field = my_field
wrap = <span>|</span>
}
[...]
}
}
Which returns lines.
I tried to add a where statement any way I could with static dates or variables... without success. My understanding of the where clause is that everything after the = is dumped as is in the SQL query. But it seems I missed something.
Basically I want the TypoScript to generate a SQL Query smilar to this :
SELECT * FROM tx_my_table WHERE effective_date < NOW() ORDER BY effective_date DESC LIMIT 1;
This should be simple. Has anyone done this in the past?
Thanks!
Your TypoScript seems to be OK.
What happens if you enter the SQL Query directly into MySQL?
Note that with your code, only one record with pid=100000 is
selected.
Have you tried this:
--
lib.my_val {
select {
pidInList = 100000
max = 1
where = UNIX_TIMESTAMP(effective_date) < UNIX_TIMESTAMP()
orderBy = UNIX_TIMESTAMP(effective_date) DESC
}
table = tx_my_table
}
TYPO3 Wiki on select

How can I select data with linq to sql from another query?

How can I select data with such linq to sql code, it's something wrong, i must compare WHERE, from st1 and st2, but something wrong. Also spaller didn't light this variables in where
var st1 = (from a in db.RouteDetail
where a.Station == "Гродно"
select new
{
a.Route,
});
var st2 = (from c in db.RouteDetail
where c.Station == "Лида"
select new
{
c.Route,
});
var res = (from d in db.RouteDetail
where st1.Route == st2.Route
select d);
Help me to do this, please.
I think what you mean to do is something like this :
var st1 = (from a in db.RouteDetail
where a.Station == "Гродно"
select new
{
a.Route,
});
var st2 = (from c in db.RouteDetail
where c.Station == "Лида"
select new
{
c.Route,
});
Both st1 and st2 now contain IQueryable types which allow you to enumerate over them. I'm assuming that your two queries only return one result in which case:
var station1 = st1.FirstorDefault();
var station2 = st2.FirstorDefault();
var res = (from d in db.RouteDetail
where station1.Route == station2.Route
select d);
Will do what you need it to do (provided they return a result theres no safety here for null exceptions). If however there is more than one result, it will only return the first match. In which case you will need to work out all the possible compositions from the values in st1 and st2