simple join of three tables in LINQ - linq

i dont understand linq properly. i dont know why.
i have three tables.
1)TillTable
tillId, tillName
1 w1
2 w2
3 w3
4 w4
2)TillDepartment
tillDeptId, tillId, deptId, isPart
1 1 5 1
2 1 7 0
3 1 8 0
4 1 9 0
5 2 5 0
6 2 7 0
7 2 8 0
8 2 9 0
9 3 5 0
10 3 7 1
11 3 8 0
12 3 9 0
13 4 5 0
14 4 7 0
15 4 9 0 so on....
3) departmentTable
deptId, deptName
5 Science
7 Commerce
8 history
9 English so on....
now using linq or lambda exp i want to display following result,
tillId, tillName, deptName
1 w1 science
2 w2 no dept
3 w3 commerce
4 w4 no dept so on...
i hope for linq master its damn easy task....
help me to get it resolved....
if isPart column is 1 then in result set deptName should be displayed else 'no dept' ....
associative table has multiple entries for tillId.....
its requirement so strictly follow this scenario only.....
i hope its clr ......

Try this:-
var result = (from tt in db.tillTables
join td in db.tillDepts
on tt.tillId equals td.tillId
join dt in db.departmentTable
on td.deptid equals dt.deptId
select new
{
tillId = tt.tillId,
tillName = tt.tillName,
deptName = td.isPart == 1 ? dt.deptName : null
}).GroupBy(x => x.tillId)
.Select(x =>
{
var orderedDeptRecord = x.OrderByDescending(z => z.deptName).FirstOrDefault();
return new
{
tillId = x.Key,
tillName = orderedDeptRecord.tillName,
deptName = orderedDeptRecord.deptName
};
});

Outer join to single record,then, the foreign key to the deptName is the select clause with ternary operator (gets translated to "case")
from t in TillTable
join tds in TillDepartment on new { t.tillId,isPart=1}
equals new { td.tillId, isPart } into tdOuter
from td in tdOuter.DefaultIfEmpty().Take(1)
select new { t.tillId, t.tillName,
deptName=((td==null)? "no dept" :
(from dt in departmentTable
where dt.deptId == td.deptId
select deptName ) ) }

Related

How to make SORTKEY for irregular observations

I'd like to make "SORTKEY" like the below. It's not the same observations for each one.
Basically, each one is 3 obs but if flg=1 then "SORTKEY" includes that observation.
In this example, it means SORTKEY = 2 is 4 obs, SORTKEY ^=2 is 3 obs.
Is there the way to make the SORTKEY manually?. If you have a good idea, please give me some advice.
I want the following dataset, using the "test" dataset.
/*
SORTKEY NO FLG
1    1  0
1    2  0
1    3  0
2    4  0
2    5  0
2    6  0
2    7  1
3    8  0
3    9  0
3    10 0
*/
data test;
input no flg;
cards;
1 0
2 0
3 0
4 0
5 0
6 0
7 1
8 0
9 0
10 0
;
run;
Use a sequence counter to track the 3-rows-per-sortkey requirement.
Example:
data want;
set have;
retain sortkey 1;
seq+1;
if seq > 3 and flag ne 1 then do;
seq = 1;
sortkey+1;
end;
run;

Coding for LINGO/LINDO (Integer Linear Programming)

I'm confused how to write the code on LINGO for this model (the model is on pic). I want the "Periode" (period on English) to be consecutive. I tried this code, it's feasible but it's not in consecutive periods. Can someone help me with this problem?
(here's the code that i tried)
SETS:
HARI/I1..I3/;
PERIODE/J1..J4/;
PERIOD/P1..P3/;
SKS/T1..T2/;
KM/K1..K4/:A;
DOSEN/L1..L4/:G;
MK/M1..M8/:H, B;
RUANGAN/N1..N3/;
JADWAL(HARI, PERIODE, KM, DOSEN, MK, RUANGAN):X;
PREFERENSI(HARI, PERIODE, DOSEN):Y;
ULANG(HARI, PERIODE, KM):Z;
CONSECUTIVE(HARI, PERIOD, KM, SKS, MK, RUANGAN):W;
ENDSETS
DATA:
H = 2 2 2 2 2 2 2 2;
B = 1 1 1 1 1 1 1 1;
G = 4 4 4 4;
A = 4 4 4 4;
ENDDATA
#FOR(HARI(I): #FOR(KM(K): #FOR(DOSEN(L): #FOR(MK(M): #FOR(RUANGAN(N): #FOR(SKS(T)|T#EQ#2: X(I,1,K,L,M,N) - X(I,T,K,L,M,N)<=0))))));
#FOR(HARI(I): #FOR(KM(K): #FOR(DOSEN(L): #FOR(MK(M): #FOR(RUANGAN(N): #FOR(PERIOD(P)|P#EQ#1#AND#P#EQ#2#AND#P#EQ#3: #FOR(SKS(T)|T#EQ#2:T+P<=4)))))));
#FOR(HARI(I): #FOR(KM(K): #FOR(DOSEN(L): #FOR(MK(M): #FOR(RUANGAN(N): #FOR(PERIOD(P)|P#EQ#1#AND#P#EQ#2#AND#P#EQ#3: #FOR(SKS(T)|T#EQ#2:-X(I,J,K,L,M,N)+X(I,P+1,K,L,M,N)-X(I,P+T,K,L,M,N)<=0)))))));
#FOR(HARI(I): #FOR(KM(K): #FOR(DOSEN(L): #FOR(MK(M): #FOR(RUANGAN(N): #FOR(SKS(T)|T#EQ#2: X(I,4,K,L,M,N) - X(I,4-T,K,L,M,N)<=0))))));

how can i return null when dividing values

I would like to get a null value when i SUM UP and divide multiple values in event any of the values that i am summing up has a null. in the example below i would like the return value to be be a null if any of the values i am summing up have a null or zero.
(((CAST (NVL(XYY.SCR,NULL)AS NUMBER) - 57.81114) / 24.79211) + ((CAST(NVL(WPM_SCR,NULL)AS NUMBER) - 40.7836082505127) / 17.5946375921401) + ((CAST (NVL(SLOT3,NULL) AS NUMBER) - 50.204190919674 ) / 25.5100093808846) ) / 3 BASE
A simplified example:
anything + null or / null will be null anyway, so you don't have to do anything about it
for + 0 or / 0, use CASE (see lines #7 and #11)
SQL> with test (a, b) as
2 (select 6, 3 from dual union all
3 select 5, 0 from dual union all
4 select 2, null from dual
5 )
6 select a, b,
7 case when b = 0 then null
8 else a/b
9 end result_div,
10 --
11 case when a = 0 or b = 0 then null
12 else a + b
13 end result_sum
14 from test;
A B RESULT_DIV RESULT_SUM
---------- ---------- ---------- ----------
6 3 2 9
5 0
2
SQL>

Hive inner joins wrong result

Two tables table1 and table 2
hive> select * from table1 where dt=20171020;
OK
a 1 1 p 10 20171020
b 2 2 q 10 20171020
c 3 3 r 10 20171020
d 4 4 r 10 20171020
hive> select * from table2 where dt=20171020;
OK
a 1 1 p 10 20171020
b 2 2 t 10 20171020
c 3 3 r 10 20171020
hive> select * from table1 t1
> join table2 t2
> on t1.c1=t2.c1
> where
> t1.dt=20171020 and t2.dt=20171020 and
> t1.c2 <> t2.c2 or t1.c3 <> t2.c3 or t1.c4 <> t2.c4 or t1.c5 <> t2.c5;
Result:
a 1 1 p 20 20171016 a 1 1 p 10 20171015
a 1 1 p 20 20171016 a 1 1 p 10 20171020
b 2 2 q 20 20171016 b 2 2 t 10 20171015
b 2 2 q 20 20171016 b 2 2 t 10 20171020
c 3 3 r 20 20171016 c 3 3 r 10 20171015
c 3 3 r 20 20171016 c 3 3 r 10 20171020
b 2 2 q 10 20171020 b 2 2 t 10 20171015
b 2 2 q 10 20171020 b 2 2 t 10 20171020
a 19 19 p 20 20171019 a 1 1 p 10 20171015
a 19 19 p 20 20171019 a 1 1 p 10 20171020
I want following row because this row got changed,how hive joins in the above code?
b 2 2 q 10 20171020
Try this.Your join should be on date as well.
SELECT *
FROM table1 t1
JOIN table2 t2
ON t1.c1 = t2.c1
AND t1.dt = t2.dt
WHERE t1.dt = 20171020
AND ( t1.c2 <> t2.c2
OR t1.c3 <> t2.c3
OR t1.c4 <> t2.c4
OR t1.c5 <> t2.c5 );

How to increment by group

There is a table and now add a new column -- sort_num int default 0
id level sort_num
1 1 0
2 1 0
3 2 0
4 2 0
5 2 0
6 3 0
7 3 0
8 3 0
9 3 0
Now I want to set sort_num values like below
id level sort_num
1 1 1
2 1 2
3 2 1
4 2 2
5 2 3
6 3 1
7 3 2
8 3 3
9 3 4
The Java code implement above requirement is
int sortNum = 0;
int currentLevel = fooList.get(0).getLevel();
for (RuleConf foo : fooList) {
if(currentLevel != foo.getLevel()){
sortNum = 0;
currentLevel = foo.getLevel();
}
foo.setSortNum(++sortNum);
}
I want to know if Java8 could simplify above code?
PS. Use mysql to implement this requirement
set #index:=0; update t set sort_num = (#index:=#index+1) where level = 1 order by id;
set #index:=0; update t set sort_num = (#index:=#index+1) where level = 2 order by id;
set #index:=0; update t set sort_num = (#index:=#index+1) where level = 3 order by id;
The best approach is to stick to your plain enhanced for loop. I don't think it is possible to come up with a single Stream solution, since you need to have intermediate values. Like:
Map<Integer, List<RuleConf>> levels = fooList.stream()
.collect(Collectors.groupingBy(RuleConf::getLevel));
levels.values().forEach(v ->
IntStream.range(0, v.size()).forEach(i -> v.get(i).setSortNum(i + 1))
);
If you keep track of the next order numbers yourself, you may do it with one stream. This solution is thread safe as well, hence should work with parallel streams:
Map<Integer, AtomicInteger> orders = new ConcurrentHashMap<>();
fooList.stream().forEachOrdered(foo -> {
orders.putIfAbsent(foo.getLevel(), new AtomicInteger());
foo.setOrder(orders.get(foo.getLevel()).incrementAndGet());
});
It should outperform the other stream-solutions, because it requires to iterate over the list only ones.

Resources