Laravel query where In with empty array clasue - laravel

I have array like this
$ans = [1,2,3];
$ans2 = [5, 4]
$ans3 = [6,7];
Syntax 1 :
$query->whereIn($field , $ans);
$query->whereIn($field1 , $ans2);
$query->whereIn($field2 , $ans3); //problem is here when array
//has null value it doesnt work as expected
so query is something like
select * from table
where field in (1,2,3)
and field1 in (5,4)
and field2 in (6,7)
result is correct because it is doing and for all field && field1 && field2
but when input has null it didn't work as expected
$ans = [1,2,3];
$ans2 = [5, 4]
$ans3 = [6,null];
now my query is
first solution
$query->whereIn($field , $ans);
$query->whereIn($field1 , $ans2);
$query->whereIn($field2 , $ans3); //problem is here when array has null value
it doesnt work as expected
this dont work as we have null in feild3 so result is []
$query->whereIn($field , $ans);
$query->whereIn($field1 , $ans2);
$searchArray = collect($field2)->filter()->all();//filter array having null values
$query->whereIn($field2, $searchArray)
$query->where($field2 , null);
so query becomes something like this
select * from table
where field in (1,2,3)
and field1 in (5,4)
and field2 in (6)
and field2 is null //wrong as field should have or in null case because i want to get field2 having 6 or null
that leads me to this
$query->whereIn($field , $ans);
$query->whereIn($field1 , $ans2);
$searchArray = collect($field2)->filter()->all();//filter array having null values
$query->whereIn($field2, $searchArray)
->orWhereNull($field2);
result is field2 having 6 and also null but not it dont take care of other fields query is like
select * from table
where field in (1,2,3)
and field1 in (5,4)
and field2 in (6)
or field2 is null //it always show results with null and 6
// but field1 and field2 are not matter are neglected
i want something like this may be this is the right approach
select * from table
where field in (1,2,3)
and field1 in (5,4)
and (field2 in (6)
or field2 is null) //extra parenthesis so field 2 should have 6 or null but it should **and** field1, field2
any hint how i can achieve filed2 when has null and a value i.e [null, 6] should do something like this
(1 ,2,3 ) && (5,4) && (6 || null)

You can use a callback in where clause
Like:
$query->where(function($q) use ($field2, $searchArray) {
$q->whereIn($field2, $searchArray)->orWhereNull($field2);
});

Make a subquery, change :
$query->where($field2 , null);
to,
$query->where('field2', function($q) use($ans3){
$q->whereIn('field2', $ans3)
->orWhereNull('field2')
})

Why not try removing/unsetting the null key before passing the array into the where query,
if array_filter($field2); doesn't work correctly
try this post Remove empty array elements

Related

Insert into table two and update table two for BigQuery in one query

I am using StandardSQL in BigQuery. I am writing a scheduled query which inserts records into table (2). Now, given that it's sceduled, I am trying to figure out how to update records in table (2) from the sceduled query, which is always inserting records into table (2).
In particular, when there is a record in table (2) but not generated by my query then I want to update table (2) and a boolean column to No.
Below is my query, where in the query would I add the update logic for table (2)?
INSERT INTO record (airport_name, icao_address, arrival, flight_number, origin_airport_icao, destination_airport_icao)
WITH
planes_stopped_in_airport AS (
SELECT
p.IATA_airport_code,
p.airport_name,
p.airport_ISO_country_code,
p.ICAO_airport_code,
timestamp,
a.icao_address,
a.latitude,
a.longitude,
a.altitude_baro,
a.speed,
heading,
callsign,
source,
a.collection_type,
vertical_rate,
squawk_code,
icao_actype,
flight_number,
origin_airport_icao,
destination_airport_icao,
scheduled_departure_time_utc,
scheduled_arrival_time_utc,
estimated_arrival_time_utc,
tail_number,
ingestion_time
FROM
`updates` a
JOIN
Polygons p
ON
1 = 1
WHERE
a.timestamp >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 20 MINUTE) and a.timestamp <= CURRENT_TIMESTAMP()
AND ( latitude IS NULL
AND longitude IS NULL
AND callsign IS NULL
AND speed IS NULL
AND heading IS NULL
AND altitude_baro IS NULL) IS FALSE
AND ST_DWithin( ST_GeogFromText( polygon ),
ST_GeogPoint(a.longitude,
a.latitude),
10)
AND a.collection_type = '1' -- and speed < 50
AND (origin_airport_icao IS NULL
AND destination_airport_icao IS NULL) IS FALSE )
SELECT
p.airport_name,
icao_address,
MIN(timestamp) AS Arrival,
flight_number,
origin_airport_icao,
destination_airport_icao
FROM
planes_stopped_in_airport p
WHERE
flight_number NOT IN (SELECT Distinct flight_number
FROM `table(2)`
)
GROUP BY
icao_address,
p.airport_name,
flight_number,
origin_airport_icao,
destination_airport_icao
HAVING
flight_number IS NOT NULL
ORDER BY
airport_name,
arrival
You can probably do it with MERGE statement, see details in https://cloud.google.com/bigquery/docs/reference/standard-sql/dml-syntax#merge_statement.
If I understood your requirements correctly, you need something like
MERGE dataset.Destination T
USING (SELECT * ...) S
ON T.key = S.key
WHEN MATCHED THEN
UPDATE SET T.foo = S.foo, T.bool_flag = FALSE
WHEN NOT MATCHED THEN
INSERT ...

No records found in AND Condition Oracle Sql Query

I have query in which I select records with data validation on table with AND Condition but only 1 Condition have no records so that it returns 0 rows. How to avoid this condition.
Query:
SELECT a.clientid, a.cnic_no, a.nrsp_status, b.projectid
FROM we_group_hof_k a, hof b
WHERE a.clientid IS NOT NULL
AND a.nrsp_status = 2
AND LENGTH(a.cnic_no) <=13
AND b.urn like '006%'
I found last Condition b.urn does not have 006%. So this query return 0 rows. I want if this condition have no records then show others records
Updated query:
INSERT INTO we_group_hof
(clientid, projectid, cnic_no, gendid, rid, mstatusid, village_id, ucid, cityid, disttid, nrsp_hofid, group_hof_id, nrsp_status, isenrolled
, cardstatus, dob, cardno)
SELECT a.clientid, a.cnic_no, a.gendid, a.rid, a.mstatusid, a.village_id, a.ucid, a.cityid, a.nrsp_hofid,
a.group_hof_id, a.nrsp_status, a.isenrolled, a.cardstatus, a.dob, LPAD(b.projectid,3,0), LPAD(b.disttid,3,0),to_char(max(b.cardno)+1)
FROM we_group_hof_k a, hof b
WHERE ((a.clientid IS NOT NULL
AND a.nrsp_status = 2
AND LENGTH(a.cnic_no) <=13
AND a.isenrolled = 'Y'
AND a.cardstatus = 'A'
AND a.dob <= sysdate
AND a.dob IS NOT NULL)
OR b.urn like '006%')
GROUP BY a.clientid, b.projectid, a.cnic_no, a.gendid, a.rid,
a.mstatusid, a.village_id, a.ucid, a.cityid, b.disttid, a.nrsp_hofid,
a.group_hof_id, a.nrsp_status, a.isenrolled, a.cardstatus, a.dob;
I tried with this query but this query did not execute and query executing not execute
It isn't clear if this is exactly what you want, but it's likely that an OR condition with proper parentheses will help you in selectively filtering the needed records.
..
WHERE
( a.clientid IS NOT NULL
AND a.nrsp_status = 2
AND LENGTH(a.cnic_no) <=13
)
OR b.urn like '006%'

Constraint check if row and other row not null on same time

I have a school 'project' to work on, which has some tables and one table needs to have a constraint which is not working out for me.
There are some tables like QUESTION, ANSWER and REACTION.
A reaction belongs with or a question or a answer but not both on the same time.
There by I have 2 rows:
question_id NUMBER,
answer_id NUMBER,
Both not null because the cant by null, but not on the same time.
I already made a constraint but isn't working..
/* CHECK if reaction belongs to an question or a answer NOT WORKING YET*/
CONSTRAINT CHECK_question_or_answer CHECK((answer_id != NULL AND question_id = NULL) OR (answer_id = NULL OR question_id != NULL))
Already tested the constraint and I can insert a value without a question_id or answer_id.
I hope it's a bit clear, if not, I am happy yo try explain myself better.
(still newby on SQL)
Thanks.
Your constraint:
CONSTRAINT CHECK_question_or_answer CHECK((answer_id != NULL AND profile_id = NULL) OR (answer_id = NULL OR profile_id != NULL))
Is always FALSE.
You need to use IS NULL or IS NOT NULL like:
CONSTRAINT CHECK_question_or_answer CHECK((answer_id IS NOT NULL AND profile_id IS NULL) OR (answer_id IS NULL OR profile_id IS NOT NULL))
This is because comparison operators != , = , > , <, combined with NULL produce NULL and are treated as false.
Demo:
SELECT 1
FROM dual
WHERE 1 IS NOT NULL;
SELECT 1
FROM dual
WHERE 1 != NULL;
From doc:
NULL values represent missing or unknown data. NULL values are used as
placeholders or as the default entry in columns to indicate that no
actual data is present. The NULL is untyped in SQL, meaning that it is
not an integer, a character, or any other specific data type.
Note that NULL is not the same as an empty data string or the
numerical value '0'. While NULL indicates the absence of a value, the
empty string and numerical zero both represent actual values.
While a NULL value can be assigned, it can not be equated with
anything, including itself.
Because NULL does not represent or equate to a data type, you cannot
test for NULL values with any comparison operators, such as =, <, or
<>.
The IS NULL and IS NOT NULL operators are used to test for NULL
values.
Do it the other way around. Put the id of the main table in the others like that
question table
--------------
id
text
...
answers table
-------------
id
question_id
text
...
reactions table
---------------
id
question_id
text
...
And question_id is never null. Then you can use a left join to get the results from both tables - one of them will have no results.
select *
from questions q
left join answers a on a.question_id = q.id
left join reactions r on r.question_id = q.id
While #lad2025s answer is good for two columns, if you wanted to extend the method to more than two it can get a bit cumbersome.
A flexible alternative is:
check ((case when answer_id is null then 0 else 1 end +
case when question_id is null then 0 else 1 end ) = 1)
It extends well to checking for a particular count of null (or non-null) values for an arbitrary number of columns.
For example, if you had column_1, column_2, column3, and column_4, and wanted at least 1 of them to be non-null, then:
check ((case when column_1 is null then 0 else 1 end +
case when column_2 is null then 0 else 1 end +
case when column_3 is null then 0 else 1 end +
case when column_4 is null then 0 else 1 end ) >= 1)

Linq and sorting null fields

I have a table that has (for example) 4 columns.
pk_table_id INT NOT NULL
username VARCHAR(100) NOT NULL
start_date DATETIME NOT NULL
end_date DATETIME NULL
My requirement is to return all rows in descending order of end_date - BUT the NULL values must be first, and then descending order of start_date.
I've done it in SQL - but could someone assist me with a LINQ version to do this?
This is the SQL query we use:
SELECT [person_employment_id]
, [party_id]
, [employer_name]
, [occupation]
, [telephone]
, [start_date]
, [end_date]
, [person_employment_type_id]
, [person_employment_end_reason_type_id]
, [comments]
, [deleted]
, [create_user]
, [create_date]
, [last_update_user]
, [last_update_date]
, [version]
FROM [dbo].[person_employment]
WHERE ([party_id]=#party_id)
ORDER BY ISNull([end_date],'9999-DEC-31') DESC, [start_date] DESC
For this problem, you could do a null check on the end_date and use that result as the ordering. So you don't need to use the same SQL constructs to achieve this, but rather use one more natural in your language of choice (C# I'm assuming).
var query =
from row in dc.Table
let isEndDateNull = row.end_date == null
orderby isEndDateNull descending, row.start_date descending
select row;

Oracle nvl in where clause showing strange results?

I have a web form that allows users to search on and edit records from an Oracle table based on parameters passed in to a proc. Here's my data:
CAE_SEC_ID SEC_CODE APPR_STATUS
1 ABC1 100
2 ABC2 100
3 ABC3 101
4 (null) 101
5 (null) 102
6 ABC4 103
And here's the where clause:
select foo
from bar
where CAE_SEC_ID = NVL(p_cae_sec_id,CAE_SEC_ID)
and Upper(SEC_CODE) like '%' || Upper(NVL(p_sec_code,SEC_CODE)) || '%'
and APPR_STATUS = NVL(p_appr_status, APPR_STATUS)
Using nvl on the parameters should return only the matched records if any of the parameters have values, and all records if none of the parameters have values. All pretty standard or so I thought. However when I do a search without any parameter values the query isn't returning records with a null SEC_CODE i.e. only records 1, 2, 3, and 6 are being returned. Shouldn't the where clause above include records with null SEC_CODE values?
The problem is that the SEC_CODE value in the table is NULL. That means that UPPER(sec_code) is NULL and your second predicate simplifies to
and NULL LIKE '%%'
Just like NULL is not equal to anything and not unequal to anything, it is not like anything. Most likely, you want something like
and (Upper(SEC_CODE) like '%' || Upper(NVL(p_sec_code,SEC_CODE)) || '%' or
(sec_code is null and p_sec_code is null))
That will return every row if P_SEC_CODE is NULL but still apply the filter if P_SEC_CODE is non-NULL.
No it shouldn't.
The SEC_CODE in the database is null, so the UPPER(SEC_CODE) is null and so it will fail on a LIKE match or pretty much any other comparison beyond IS NULL. Technically it is a UNKNOWN rather than a FALSE but is isn't enough to pass the test.
The expression NULL = NULL evaluates to NULL, which is not true and so these rows won't be returned. If I understand the requirement correctly, you only want to filter if a parameter is different from null, so I would rewrite the query like this to make the filter more explicit:
select foo from bar
where (p_cae_sec_id is null or CAE_SEC_ID = p_cae_sec_id)
and (p_sec_code is null or Upper(SEC_CODE) like '%' || Upper(p_sec_code) || '%')
and (p_appr_status is null or APPR_STATUS = p_appr_status)
Setting the p_sec_code parameter to null will now return all rows, ignoring the value in the SEC_CODE column.
We can also write the Jorn's query like
select foo from bar
where (CASE WHEN p_cae_sec_id is null THEN 'Y'
WHEN CAE_SEC_ID = p_cae_sec_id THEN 'Y'
ELSE 'N'
END)='Y'
and (CASE WHEN p_sec_code is null THEN 'Y'
WHEN Upper(SEC_CODE) like '%' || Upper(p_sec_code) || '%' THEN 'Y'
ELSE 'N'
END)='Y'
and (CASE WHEN p_appr_status is null THEN 'Y'
WHEN APPR_STATUS = p_appr_status THEN 'Y'
ELSE 'N'
END)='Y'
to make it concrete and increase the performance .

Resources