when i use
$this->db->where('field !=', 1);
i want to select all entries where field is not 1. so that means here 0 or NULL
however in codeigniter he doesn't select it where the entry is NULL (default value).
how to solve this without changing the database?
dave
NULL values need to be handled separately with another where clause:
$this->db->where('field <>', 1)->or_where('field IS NULL', NULL);
It has nothing to do with Codeigniter. It's a MySQL matter.
Related
I have this UPDATE in MonetDB (version 11.41.11):
with t as (select distinct cod_atc_nl_1 , desc_atc_nl_1 from uruguay.staging_rm_dims where desc_atc_nl_1 is not null order by 1)
update uruguay.staging_rm_dims
set
desc_atc_nl_1 = t.desc_atc_nl_1,
desc_atc_nl_2 = t.desc_atc_nl_1,
desc_atc_nl_3 = t.desc_atc_nl_1,
desc_atc_nl_4 = t.desc_atc_nl_1
where
desc_atc_nl_1 is null
and desc_atc_nl_2 is null
and desc_atc_nl_3 is null
and desc_atc_nl_4 is null
and cod_atc_nl_4 is not null
and cod_atc_nl_1 = t.cod_atc_nl_1;
When I executing this sentence, I get the following error:
SQL Error [42S22]: SELECT: no such column 't.cod_atc_nl_1'
Is sintax incorrect?
Thank you.
This was an issue fixed at the version 11.41.1. The with relation must be specified on the from clause.
This is my query:
select count(*)
FROM TB_E2V_DOCUMENTOS_CICLO D
WHERE (D.TIPOCLIENTE = null or null is null)
AND (D.TIPODOCUMENTOCLIENTE = null or null is null)
AND (D.NUMDOCUMENTOCLIENTE = null or null is null)
AND (D.BA = null or null is null)
AND (D.FA = null or null is null)
AND (D.NOMBRECLIENTE = null or null is null)
AND (D.NUMTELEFONO = null or null is null)
AND (D.NUMSUSCRIPCION = null or null is null)
AND (D.TIPORECIBO in ('Recibo'))
AND (D.NUMRECIBO = null or null is null)
AND (TO_DATE(D.FECHAEMISION, 'yyyy/MM/dd') BETWEEN TO_DATE('2019-5-1', 'yyyy-MM-dd') AND TO_DATE('2020-2-18', 'yyyy-MM-dd'))
AND (D.MONTORECIBO = null or null is null)
AND (D.NUMPAGINAS = 0 or 0 = 0)
AND (D.NOMBREARCHIVO = null or null is null)
AND (D.NEGOCIO = null or null is null)
AND (D.NOMBREMETADATACARGA = null or null is null)
AND (D.FECHACARGA = TO_DATE(null) or TO_DATE(null) is null);
This query returns
And when I do a Xplain For:
The cost is very high, but this query uses the index. The query lasts 10 seconds approximately.
How can I improve the performance of the query?
I'm using Oracle 12c
Notes: All of the " and ( = null or null is null)" predicates will always evaluate to true; Oracle does not define null so null does not equal null, so instead if you want to check for null then use "is null"
select * from dual where null = null; -- returns no rows
select * from dual where not (null <> null); -- returns no rows
select * from dual where null is null; -- returns 1 row
select * from dual where not(null is not null); -- returns 1 row
As far as indexing goes, you need an index that is selective (i.e. return much fewer rows) and is present in the where clause predicate. In this case it looks like a function-based index on TO_DATE(D.FECHAEMISION, 'yyyy/MM/dd')
along with D.TIPORECIBO is in order. The INDEX SKIP SCAN is used in this case probably because D.TIPORECIBO is not the leading column; INDEX SKIP SCANs are slower then INDEX RANGE SCANs because it needs to read more index blocks.
There are a few factors involved here:
First, this query is using the second (or third) part of a composite index, resulting in the SKIP SCAN.
Take a look at all indexes on the table and see what kind of index is on TIPORECIBO.
It is likely that this isn't the leading column. You might improve the performance by creating an index with TIPORECIBO as leading column, but it is unlikely--this appears to be a "type" column that might have only a few values, and not a good candidate for an index.
The second issue is that Oracle uses the index to get a set of candidate rows, then goes to the data blocks themselves to get the rows for further filtering.
A select count(*) will perform much better if Oracle doesn't need to fetch the data blocks. This can be achieved by creating an index that contains all of the data needed for the filter.
In your case, an index on TIPORECIBO and FECHAEMISION would mean that Oracle could go to the index alone without needing to access the data blocks.
The third issue is that you are applying TO_DATE to the FECHAEMISION column. If this is a DATE datatype, then you don't need the conversion and it is causing you trouble. If you do need the conversion, an option would be a function-based index on TO_DATE(D.FECHAEMISION, 'yyyy/MM/dd').
To tune this particular query, you can try a function-based composite index:
CREATE INDEX TB_E2V_DOCUMENTOS_CICLO_FX1 ON TB_E2V_DOCUMENTOS_CICLO(FECHAEMISION, TO_DATE(D.FECHAEMISION, 'yyyy/MM/dd'))
Finally, this query is clearly being generated from code:
lines like AND (D.BA = null or null is null) seem to be a way of excluding portions of the WHERE clause when the front-end passes a NULL. This would possibly be AND (D.BA = 'X' or 'X' is null) if a value were provided for that parameter.
As such, be careful when tuning for the current set of parameters, as any change in what generated this query will impact the effectiveness of your tuning.
If you have a way to influence how this query is generated, it would be nice to simply exclude those non-event filters when the values are not provided, though Oracle ought to be able to handle them as-is.
I can't figure out how to set a field to null on certain condition. It should be an easy query but I'n not able to set the right value for NULL on a nullable field.
Product::where('id', $product_list)->update(['family_id' => null]);
nor
Product::where('id', $product_list)->update(['family_id' => DB::raw(null)]);
did the trick.
Both cases compiled fine but the generated query seems to be wrong because I get a SQL error. In the irst case the error is :
SQLSTATE[HY093]: Invalid parameter number (SQL: update `products` set `family_id` = ?, `products`.`updated_at` = 2019-11-12 08:41:07 where `id` = ?)
and the error for the second one is :
QLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ', `products`.`updated_at` = ? where `id` = ?' at line 1 (SQL: update `products` set `family_id` = , `products`.`updated_at` = 2019-11-12 08:21:50 where `id` = ?)
In the first case it seems that NULL is not being added to the parameters to the prepared query, and in the secon the NULL value is being inserted as nothing in the query. There is any simple way to set the value to NULL?
You should consider the following things first.
1) family_id column is nullable in your table. if not then set nullable.
2) Make sure you have in $fillable property of Product model column family_id.
Make sure $product_list returns id of that particular product.
if $product_list is collection/array of product data then use like:
Product::where('id', $product_list->id)->update(['family_id' => null]);
Try this
Product::where('id', $product_list)->update(['family_id' => 'NULL']);
First question is do both of these work:
WHERE PROJECT_ID IN ('&PROJECT_ID', NULL)
(PROJECT_ID = '&PROJECT_ID' OR PROJECT_ID IS NULL)
And second is if so which is best or is there a better / working alternative?
Essentially want all project id's and records with null to be returned.
Thanks in advance
WHERE PROJECT_ID = '&PROJECT_ID'
AND PROJECT_ID IS NOT NULL
I'm trying to understand why my query is returning things in a different order than I expect.
My query is:
SELECT 'PRINTJOBID', MAX(PRINTJOBID), null, null FROM PRINTJOB
UNION
SELECT 'AUTOID', null, MAX(AUTOID), null FROM PRINTJOBSHELLS
UNION
SELECT 'PROCESSLOGID', null, null, MAX(PROCESSLOGID) FROM PROCESSLOG;
I am expecting it to give me 3 rows, with printjobid at the top, followed by autoid, and then at the bottom should be processlogid. However, when I run the query I get autoid at the top, printjobid in the middle, and processlog at the bottom, like this:
AUTOID null 771426 null
PRINTJOBID 76401 null, null
PROCESSLOGID null null 1218693
I have tried googling about Unions being in the wrong order, and I tried searching questions on SO. I didn't see anything that seemed relevant. Is my understanding of how UNION works faulty? I thought that the query would return the rows in the order I put the select statements. Thank you!
In SQL, you can't rely on a query returning results in any special order unless you explicitly specify it in the query.
Use this:
SELECT title, v1, v2, v3
FROM (
SELECT 'PRINTJOBID' title, MAX(PRINTJOBID) v1, null v2, null v3, 1 AS o
FROM PRINTJOB
UNION ALL
SELECT 'AUTOID' title, null, MAX(AUTOID), null, 2 AS o
FROM PRINTJOBSHELLS
UNION ALL
SELECT 'PROCESSLOGID' title, null, null, MAX(PROCESSLOGID), 3 AS o
FROM PROCESSLOG
)
ORDER BY
o
If you want ordering of results, you need to specify an ORDER BY clause. Otherwise you are relying on implementation-specific behaviour. In this case it is probably lucky you did not get the ordering you hoped for originally, as the behaviour could easily change in future, so you need to explicitly specify ordering if it is important to you.