Laravel / Eloquent whereIn with null - eloquent

How do I apply Laravel's Eloquent whereIn() so that it includes null?
I've tried:
User::whereIn("column", [null, 1, 2]) -> get();
And
User::whereIn("column", [DB::raw("null"), 1, 2]) -> get();
But both queries return no results.
Thanks!

I don't think you can pass null in in mysql statement. If you run the query in mysql console it will skip the null.
Try User::whereNull('column')->orWhereIn('column', array(1, 2))->get();

Fetching data with either null and value on where conditions are very tricky. Even if you are using straight Where and OrWhereNotNull condition then for every rows you will fetch both items ignoring other where conditions if applied. For example if you have more where conditions it will mask out those and still return with either null or value items because you used orWhere condition. Just like #Angelin Calu mentioned above in comment section.
The best way so far I found is as follows. This works as where (whereIn Or WhereNotNull).
User::where(function ($query) {
$query->whereIn('column',[1,2])->orWhereNull('column');
})->get();

Related

How to write proper boolean comparison for PostgreSQL in JOOQ

I have a table t with boolean column b.
db.select(T.B).from(T).where(T.B.isTrue()).fetch();
db.select(T.B).from(T).where(T.B.eq(Boolean.TRUE)).fetch();
both these statements are translated to same sql query:
select "public"."T"."B" from "public"."T" where "public"."T"."B" = true;
and this is not working because for boolean comparison keywoard "is" must be used:
select "public"."T"."B" from "public"."T" where "public"."T"."B" is true;
Is there a way to write this properly?
jOOQ currently doesn't support the SQL <boolean test> expression (i.e. x IS [ NOT ] <truth value>)
However, in the "true" case, this isn't really necessary anyway. You can pass the column to the where clause directly:
where(T.B)
... for the same effect. To get the inverse predicate, you can write
where(not(T.B))
If you want a null-safe comparison, you can also use Field.isNotDistinctFrom() or Field.isDistinctFrom()
where(T.B.isNotDistinctFrom(true))
where(T.B.isDistinctFrom(true))

How to use tSQL to match and remove everything after a string?

How can I use tSQL to find a string, and if it exists, return everything before that string?
i.e. in the example below, in an ETL process, how would we take the column from source, identify the string ?uniquecode= and therefore remove that, and everything else after it, in the SELECT statement for the sink column?
How can I best modify this tSQL statement below to return the values in SinkPageURL column above?
SELECT SourcePageURL FROM ExampleTable
I have attempted a Fiddle here - http://sqlfiddle.com/#!18/3b60a/4 using the below statement. It is disregarding the values where '?uniquecode=' does not exist though, and also leaves the '?' symbol. Need this to work with MS SQL Server '17.
Somewhat close, but no cigar. Help appreciated!
SELECT LEFT(SourcePageURL, CHARINDEX('?uniquecode=', SourcePageURL)) FROM sql_test
Try this query:
SELECT
CASE WHEN CHARINDEX('?uniquecode=', SourcePageURL) > 0
THEN SUBSTRING(SourcePageURL,
1,
CHARINDEX('?uniquecode=', SourcePageURL) - 1)
ELSE SourcePageURL END AS new_source
FROM sql_test;
If you instead wanted to update the source URLs in your example using this logic, you could try the following:
UPDATE sql_test
SET SourcePageURL = SUBSTRING(SourcePageURL,
1,
CHARINDEX('?uniquecode=', SourcePageURL) - 1)
WHERE SourcePageURL LIKE '%?uniquecode=%';

Filtering one of the columns in an MDX query

I am comparatively new to MDX. I am working witht he following query :-
WITH
SET [Organisation Default Member]
AS
STRTOMEMBER(iif(isempty(LadbrokesSAS.GetDimensionSecurityUserDefaultOrgMember(USERNAME)),"[Organisation].[Organisation Hierarchy].[ALL]",LadbrokesSAS.GetDimensionSecurityUserDefaultOrgMember(USERNAME)),CONSTRAINED)
MEMBER [Measures].[ParameterCaption] AS '[Organisation].[Organisation Hierarchy].CURRENTMEMBER.MEMBER_CAPTION'
MEMBER [Measures].[ParameterValue] AS '[Organisation].[Organisation Hierarchy].CURRENTMEMBER.UNIQUENAME'
MEMBER [Measures].[ParameterLevel] AS '[Organisation].[Organisation Hierarchy].CURRENTMEMBER.LEVEL.ORDINAL'
MEMBER [Measures].[ParameterCaptionIndented] AS Space([Organisation].[Organisation Hierarchy].CURRENTMEMBER.LEVEL.ORDINAL) + [Organisation].[Organisation Hierarchy].CURRENTMEMBER.MEMBER_CAPTION
SET [Organisation]
AS Descendants([Organisation Default Member] ,[Organisation].[Organisation Hierarchy]. [Key Organisation],SELF_AND_BEFORE)
SELECT
{
[Measures].[ParameterValue]
,[Measures].[ParameterCaptionIndented]
} ON COLUMNS ,
{Organisation}
ON ROWS
FROM [ShopTradingCube]
The above query returns results like below:-
Now I want to filter the ParameterValue such that if it contains a value containing '[Organisation].[Organisation Hierarchy].[Supervisor - HO Manager]' it should not include that in the results. eg. [Organisation].[Organisation Hierarchy].[Supervisor - HO Manager].&[L7_Z_250_Closed]
I tried approaches using a where condition or by using an Except function. However, I always got some error no matter what all I tried. Can someone please let me know what should be my syntax and what is the most efficient way to achieve this?
Modify your set to the following:
SET [Organisation]
AS Descendants([Organisation Default Member] ,[Organisation].[Organisation Hierarchy]. [Key Organisation],SELF_AND_BEFORE)
-
Descendants([Organisation].[Organisation Hierarchy].[Supervisor - HO Manager])
This works like except.

EntityFramework counting of query results vs counting list

Should efQuery.ToList().Count and efQuery.Count() produce the same value?
How is it possible that efQuery.ToList().Count and efQuery.Count() don't produce the same value?
//GetQuery() returns a default IDbSet which is used in EntityFramework
using (var ds = _provider.DataSource())
{
//return GetQuery(ds, filters).Count(); //returns 0???
return GetQuery(ds, filters).ToList().Count; //returns 605 which is correct based on filters
}
Just ran into this myself. In my case the issue is that the query has a .Select() clause that causes further relationships to be established which end up filtering the query further as the relationship inner join's constrain the result.
It appears that .Count() doesn't process the .Select() part of the query.
So I have:
// projection created
var ordersData = orders.Select( ord => new OrderData() {
OrderId = ord.OrderId,
... more simple 1 - 1 order maps
// Related values that cause relations in SQL
TotalItemsCost = ord.OrderLines.Sum(lin => lin.Qty*lin.Price),
CustomerName = ord.Customer.Name,
};
var count = ordersData.Count(); // 207
var count = ordersData.ToList().Count // 192
When I compare the SQL statements I find that Count() does a very simple SUM on the Orders table which returns all orders, while the second query is a monster of 100+ lines of SQL that has 10 inner joins that are triggered by the .Select() clause (there are a few more related values/aggregations retrieved than shown here).
Basically this seems to indicate that .Count() doesn't take the .Select() clause into account when it does its count, so those same relationships that cause further constraining of the result set are not fired for .Count().
I've been able to make this work by explicitly adding expressions to the .Count() method that pull in some of those aggregated result values which effectively force them into the .Count() query as well:
var count = ordersData.Count( o=> o.TotalItemsCost != -999 &&
o.Customer.Name != "!##"); // 207
The key is to make sure that any of the fields that are calculated or pull in related data and cause a relationship to fire, are included in the expression which forces Count() to include the required relationships in its query.
I realize this is a total hack and I'm hoping there's a better way, but for the moment this has allowed us at least to get the right value without pulling massive data down with .ToList() first.
Assuming here that efQuery is IQueryable:
ToList() actually executes a query. If changes to data in the datastore, between calls to ToList() and .Count(), result in a different resultset, calling ToList() will repopulate the list. ToList().Count and .Count() should then match until the data in the store changes the resultset again.

Zend Framework: Re-use WHERE clause returned from Zend_Db_Select::getPart()

I have a SELECT object which contains a WHERE.
I can return the WHERE using getPart(Zend_Db_Select::WHERE), this returns something like this:
array
0 => string "(clienttype = 'agent')"
1 => string "AND (nextpayment < (NOW() - INTERVAL 1 DAY))"
This array seems pretty useless as I cannot do this with it
$client->update(array("paymentstatus" => "lapsed"), $where);
Or even put it into another SELECT object. Is there a way of getting a more useful representation of the WHERE statement from the SELECT object?
Thanks
EDIT
The best I have come up with so far is
$where = new Zend_Db_Expr(implode(" ", $select->getPart(Zend_Db_Select::WHERE)));
Your first choice, $client->update(...) would work, if getParts omitted the 'AND' from the second part of the where clause.
I'm pretty sure your only choice is to:
use your second option (probably safest depending on how complex the where clauses are) -or-
iterate through the $where returned and remove the leading 'AND', 'OR' that may exist.