Multi-column check constraints - oracle

I have a "movies" table and I need to add a constraint to the effect that "Steven Spielberg" movies must be before 1990 and "James Cameron" movies must be after 1990.
I am new to Oracle SQL. I tried some queries but they did not work. Something like
alter table movie_16bce1346 add constraint chk_spk
if director='Steven Spielberg' then check (year>1990);
What's the right way to write this constraint?

The constraint should be something like this:
( director not in ('Steven Spielberg', 'James Cameron') or
director is null /* if that is allowed */ or
director = 'Steven Spielberg' and movie_year < 1990 or
director = 'James Cameron' and movie_year > 1990 )
You could use parentheses around the AND-separated conditions in lines 3 and 4, if you don't trust your developers to be very familiar and comfortable with the precedence of AND and OR.

You can use a CASE statement within a CHECK constraint:
ALTER TABLE movie_16bce1346
ADD CONSTRAINT check_year CHECK
(CASE
WHEN director = 'Steven Spielberg' AND movie_year > 1990 THEN 1
WHEN director = 'James Cameron' AND movie_year < 1990 THEN 1
WHEN director NOT IN ('Steven Spielberg', 'James Cameron') THEN 1
ELSE 0 END = 1);
The CASE captures your conditions, which need to return a 1 or 0. The "END = 1" says that the result of the CASE needs to equal 1.

Related

GLua - Getting the difference between two tables

Disclaimer: This is Glua (Lua used by Garry's Mod)
I just need to compare tables between them and return the difference, like if I was substrating them.
TableOne = {thing = "bob", 89 = 1, 654654 = {"hi"}} --Around 3k items like that
TableTwo = {thing = "bob", 654654 = "hi"} --Same, around 3k
function table.GetDifference(t1, t2)
local diff = {}
for k, dat in pairs(t1) do --Loop through the biggest table
if(!table.HasValue(t2, t1[k])) then --Checking if t2 hasn't the value
table.insert(diff, t1[k]) --Insert the value in the difference table
print(t1[k])
end
end
return diff
end
if table.Count(t1) != table.Count(t2) then --Check if amount is equal, in my use I don't need to check if they are exact.
PrintTable(table.GetDifference(t1, t2)) --Print the difference.
end
My problem being that with only one of difference between the two tables, this returns me more than 200 items. The only item I added was a String. I tried many other functions like this one but they usually cause a stack overflow error because of the table's length.
Your problem is with this line
if(!table.HasValue(t2, t1[k])) then --Checking if t2 hasn't the value
Change it to this:
if(!table.HasValue(t2, k) or t1[k] != t2[k]) then --Checking if t2[k] matches
Right now what is happening is that you're looking at an entry like thing = "bob" and then you're looking to see whether t2 has "bob" as a key. And it doesn't. But neither did t1 so that shouldn't be regarded as a difference.

LINQ groupby on conditional columns

I am building a report from a table that contains the details of a medical chart audit. The significant columns are:
[ProcedureCode] char(5) = Procedure / service performed
[ModifierCode1] varchar(2) = Indicator of non-standard delivery of procedure
[AuditIssueId] int = what was wrong with the use of the procedure and/or modifier code
There may be 0 or many rows per chart. Two of the AuditIssueIds are for:
Incorrect procedure code
Incorrect modifier code
The report groups results by the AuditIssue with subgroups by provider and then each procedure or modifier code reviewed (with counts of all charts / issues found / percent). Here is the first query that gets the chart count:
var providerCharts =
from ad in db.AuditDetails
join p in providers on ad.ProviderId equals p.ProviderId
where ad.ReviewDate >= startDate && ad.ReviewDate <= endDate
&& (filterSpecialtyId == 0 || p.Specialty.SpecialtyId == filterSpecialtyId)
group ad by new { ad.ProviderId, ad.ProcedureCode } into grpIssue
select new
{
ProviderId = grpIssue.Key.ProviderId,
ProcedureCode = grpIssue.Key.ProcedureCode,
ChartCount = grpIssue.Count()
};
This works great, except for one AuditIssue - "Incorrect Modifier Code". This code shows the count for each procedure in the chart but should instead be grouped by modifier.
I have attempted to insert a condition such as this in my grouping with no luck:
(i.AuditIssueId == AuditIssueIds.IncorrectModifierCode)
? ad.ModifierCode1 : ad.ProcedureCode
Do I need to do two queries and union them, or is there a method to achieve this type of dynamic grouping?
Thanks,
Scott

Efficiency of my function with Lua tables

I have a question about the way I put together this piece of Lua code.
Say, there is a function like the one below, containing 200 myTable tables, where the names are ordered alphabetically:
function loadTable(x)
local myTable
if x == "aaron" then myTable = {1,2,3,4,5,6,7,8,9,0}
elseif x == "bobby" then myTable = {1,3,3,4,5,8,7,8,9,1}
elseif x == "cory" then myTable = {1,2,3,3,3,6,7,8,9,2}
elseif x == "devin" then myTable = {1,2,3,4,5,2,3,4,9,0}
...
else
print("table not available")
end
return myTable
end
and now I want to find the table corresponding to x == "zac" (which happens to be somewhere at the end). I use this line of code:
local foundTable = loadTable("zac")
Isnt this like not efficient at all? If it has to find the table at the very end of the function it has to go through all the previous lines of code. Is there some way to code this more efficiently in lua and find the correct table faster? ?
This can become a lot faster by using... a table!
Simply make a table whose keys are the name of the person and the values are the table you want to load, like this:
local tables = {
john = {1,2,3,4,5,6,7,8,9,0},
peter = {1,3,3,4,5,8,7,8,9,1},
william = {1,2,3,3,3,6,7,8,9,2},
victoria = {1,2,3,4,5,2,3,4,9,0}
--...
}
Then, instead of calling loadTable("richard") simply use tables["richard"] or tables.richard if the key is a valid identifier

Regroup By in PigLatin

In PigLatin, I want to group by 2 times, so as to select lines with 2 different laws.
I'm having trouble explaining the problem, so here is an example. Let's say I want to grab the specifications of the persons who have the nearest age as mine ($my_age) and have lot of money.
Relation A is four columns, (name, address, zipcode, age, money)
B = GROUP A BY (address, zipcode); # group by the address
-- generate the address, the person's age ...
C = FOREACH B GENERATE group, MIN($my_age - age) AS min_age, FLATTEN(A);
D = FILTER C BY min_age == age
--Then group by as to select the richest, group by fails :
E = GROUP D BY group; or E = GROUP D BY (address, zipcode);
-- The end would work
D = FOREACH E GENERATE group, MAX(money) AS max_money, FLATTEN(A);
F = FILTER C BY max_money == money;
I've tried to filter at the same time the nearest and the richest, but it doesn't work, because you can have richest people who are oldest as mine.
An another more realistic example is :
You have demands file like : iddem, idopedem, datedem
You have operations file like : idope,labelope,dateope,idoftheday,infope
I want to return operations that matches demands like :
idopedem matches ideope.
The dateope must be the nearest with datedem.
If datedem - date_ope > 0, then I must select the operation with the max(idoftheday), else I must select the operation with the min(idoftheday).
Relation A is 5 columns (idope,labelope,dateope,idoftheday,infope)
Relation B is 3 columns (iddem, idopedem, datedem)
C = JOIN A BY idope, B BY idopedem;
D = FOREACH E GENERATE iddem, idope, datedem, dateope, ABS(datedem - dateope) AS datedelta, idoftheday, infope;
E = GROUP C BY iddem;
F = FOREACH D GENERATE group, MIN(C.datedelta) AS deltamin, FLATTEN(D);
G = FILTER F BY deltamin == datedelta;
--Then I must group by another time as to select the min or max idoftheday
H = GROUP G BY group; --Does not work when dump
H = GROUP G BY iddem; --Does not work when dump
I = FOREACH H GENERATE group, (datedem - dateope >= 0 ? max(idoftheday) as idofdaysel : min(idoftheday) as idofdaysel), FLATTEN(D);
J = FILTER F BY idofdaysel == idoftheday;
DUMP J;
Data in the 2nd example (note date are already in Unix format) :
You have demands file like :
1, 'ctr1', 1359460800000
2, 'ctr2', 1354363200000
You have operations file like :
idope,labelope,dateope,idoftheday,infope
'ctr0','toto',1359460800000,1,'blabla0'
'ctr0','tata',1359460800000,2,'blabla1'
'ctr1','toto',1359460800000,1,'blabla2'
'ctr1','tata',1359460800000,2,'blabla3'
'ctr2','toto',1359460800000,1,'blabla4'
'ctr2','tata',1359460800000,2,'blabla5'
'ctr3','toto',1359460800000,1,'blabla6'
'ctr3','tata',1359460800000,2,'blabla7'
Result must be like :
1, 'ctr1', 'tata',1359460800000,2,'blabla3'
2, 'ctr2', 'toto',1359460800000,1,'blabla4'
Sample input and output would help greatly, but from what you have posted it appears to me that the problem is not so much in writing the Pig script but in specifying what exactly it is you hope to accomplish. It's not clear to me why you're grouping at all. What is the purpose of grouping by address, for example?
Here's how I would solve your problem:
First, design an optimization function that will induce an ordering on your dataset that reflects your own prioritization of money vs. age. For example, to severely penalize large age differences but prefer more money with small ones, you could try:
scored = FOREACH A GENERATE *, money / POW(1+ABS($my_age-age)/10, 2) AS score;
ordered = ORDER scored BY score DESC;
top10 = LIMIT ordered 10;
That gives you the 10 best people according to your optimization function.
Then the only work is to design a function that matches your own judgments. For example, in the function I chose, a person with $100,000 who is your age would be preferred to someone with $350,000 who is 10 years older (or younger). But someone with $500,000 who is 20 years older or younger is preferred to someone your age with just $50,000. If either of those don't fit your intuition, then modify the formula. Likely a simple quadratic factor won't be sufficient. But with a little experimentation you can hit upon something that works for you.

Linq assign values from one table into another

I am trying to lookup a value of an column from another table and later use the new looked up values in my where clause. For example, I have the following tables below
ID Name
1 Jan
2 Feb
3 March
Product Customer Start End
A C Feb March
A B Jan March
B C March Jan
In the example above, I need to query for the list of records where Start ID is greater than the End ID. For example, B-C-March-Jan is the record I am looking for.
Should I be using join? Also, if possible a query syntax would be very helpful.
My query:
var vInvalidStartEnd = from p in vRecords
where (from t in vTimePeriods where t.Name == p["Start"] select t.TID).First().Cast<int>() > (from t in vTimePeriods where t.TName == p["End"] select t.ID).First().Cast<int>()
select new
{
Product = p["Product"],
Location = p["Location"],
Start = p["Start"],
End = p["End"]
};
Thanks
Assuming ID defines what name is later than another. Tim's issue in comments is probably because, first, it's unusual to use the name value as your link instead of the ID, and second, ID is a poor indication of which month is greater than another. If I had to use month names the way you are, I would probably have an id, a name, and then an order value in the vTimePeriods table.
from p in vRecords
join start in vTimePeriods on p["Start"] equals start["Name"]
join end in vTimePeriods on p["End"] equals end["Name"]
where (int)end["ID"] < (int)start["ID"]
select new
{
Product = p["Product"],
Location = p["Location"],
Start = p["Start"],
End = p["End"]
};
I don't know the specifics of Linq to Dataset, but it would look something like that.

Resources