Eloquent how to return null - eloquent

I have the following query:
SELECT null as id, null as cost, null as title FROM books LIMIT 1
It returns one single record.
Using Eloquent, I've tried
$listagem = Book::where('id','=',-1)->get();// there is no id = -1
$listagem = Livro::select('NULL as id' ,'NULL as cost', 'NULL as title')->get();
(...)
but nothing works.
What is the correct sintax?
Thanks

Related

CASE query in postgres does not return expected output

In my Postgres database, I am trying to execute the below query:
with
user_details as
(
SELECT username
FROM user_management WHERE username = 'admin'
)
select (case
when user_details.username is NOT NULL then 'user found'
else
'no user found' end) as username from user_details
The above query will return the username and works as expected. But if I pass the username that does not exist in the database, then I expect the CASE query to return 'no user found' but the query does not return anything at all.
But when I tried to execute the below query:
select (case
when (SELECT username
FROM user_management WHERE username = 'sadmin') is not null then 'user found'
else
'no user found' end) as username
It works as expected and returns the 'no user found'.
Why didn't I get the expected output when using the WITH query in the first case? Is there something with the WITH queries that I am missing?
When you're selecting the output from user_details , you're getting 0 rows , that is the reason you're not seeing any o/p in final result. And in the 2nd query , you're selecting the o/p from sub-query which is null then producing user not found. You might run into an error like this
ERROR: more than one row returned by a subquery used as an expression .
When there is more user having the same username. So your query should look like this
select (case
when exists(SELECT username
FROM user_management WHERE username = 'sadmin') then 'user found'
else
'no user found' end) as username
I assume that the column username is unique in the table user_management, so the CTE returns either 1 row when the username exists in the table or nothing if it does not exist.
Maybe you think that the CTE returns NULL in the case where the username does not exist in the table, but it is not.
So if the CTE returns 1 row (the username exists) then your code works fine, but if it returns nothing then your SELECT statement that selects from user_details will also return nothing, because there are no rows to select from.
Use aggregation so that you will get 1 row in the results even if the user does not exist:
SELECT COALESCE(MAX(username), 'no user found') username
FROM user_management
WHERE username = 'admin'
See the demo.

Select JSON value from a EAV structure result set

Given a result set which is in the EAV structure such as :
id | attributeName | stringValue | intValue | BooleanValue
---------------------------------------------------------------
1 stringFoo v1
1 stringFooList v2
1 stringFooList v3
1 intFoo 10
1 intFooList 10
1 intFooList 20
1 booleanFoo true
1 booleanFooList true
1 booleanFooList true
How can I select all the attributes and value pair as a single value in a JSON/JSONB format , which are something likes:
{
"stringFoo" : "v1" ,
"stringFooList" : ["v2","v3"] ,
"intFoo" : 10 ,
"intFooList" : [10,20],
"booleanFoo" : true,
"booleanFooList" : [true,true]
}
If there are multiple attribute value for an attribute such as stringFooList , it will format it as JSON array.
I am using PostgreSQL 9.6
You can do something like this:
select id, jsonb_object_agg(att, value)
from (
select id,
attributename as att,
case
when count(*) > 1 then
jsonb_agg(coalesce(stringvalue,intvalue::text,booleanvalue::text))
else
to_jsonb(min(coalesce(stringvalue,intvalue::text,booleanvalue::text)))
end as value
from eav
group by id, attributename
) t
group by id;
The inner select aggregates multiple values into an JSON array, single values into JSON scalar values. And the outer query then builds a single JSON value of all rows.
Online example: https://rextester.com/TLCRN79815
#a_horse_with_no_name 's answer gives me a good start. I extend his/her answer and come up the following query such that the elements in the JSON array have the same data type of what defined in PostgreSQL.
select id, jsonb_object_agg(att,
case
when strval is not null then strval
when intvalue is not null then intvalue
else boolVal
end
)
from (
select id,
attributename as att,
case when count(*) > 1 then
jsonb_agg(stringvalue) filter (where stringvalue is not null)
else
to_jsonb(min(stringvalue) filter (where stringvalue is not null))
end as strVal,
case when count(*) > 1 then
jsonb_agg(intvalue) filter (where intvalue is not null)
else
to_jsonb(min(intvalue) filter (where intvalue is not null))
end as intvalue,
case when count(*) > 1 then
jsonb_agg(booleanvalue) filter (where booleanvalue is not null)
else
to_jsonb(bool_and(booleanvalue) filter (where booleanvalue is not null))
end as boolVal
from eav
group by id, attributename
) t
group by id;

Why selectrow_array does not work with null values in where clause

I am trying to fetch the count from SQL server database and it gives 0 for fields with null values. Below is what I am using.
my $sql = q{SELECT count(*) from customer where first_name = ? and last_name = ?};
my #bind_values = ($first_name, $last_name);
my $count = $dbh->selectrow_array($sql, undef, #bind_values);
This returns 0 if either value is null in the database. I know prepare automatically makes it is null if the passed parameter is undef, but I don't know why it's not working.
So here is weird observation. When I type the SQL with values in Toda for SQL server, it works :
SELECT count(*) from customer where first_name = 'bob' and last_name is null
but when I try the same query and pass values in the parameter for the first_name = bob and the last_name {null} . it does not work.
SELECT count(*) from customer where first_name = ? and last_name = ?
For NULL in the WHERE clause you simply need a different query. I write them below each other, so you can spot the difference:
...("select * from test where col2 = ?", undef, 1);
...("select * from test where col2 is ?", undef, undef);
...("select * from test where col2 is ?", undef, 1);
...("select * from test where col2 = ?", undef, undef);
The first two commands work, stick to those. The third is a syntax error, the fourth is what you tried and which indeed does not return anything.
The DBI manpage has a section of NULL values that talks about this case a bit more.
So, here it is what I did. I added or field is null statement with each field if the value is undef.
my $sql = q{SELECT count(*) from customer where (first_name = ? or (first_name is null and ? = 1)) and (last_name = ? or (last_name is null and ? = 1))};
my #bind_values = ($first_name, defined($first_name)?0:1, $last_name, defined($last_name)?0:1);
my $count = $dbh->selectrow_array($sql, undef, #bind_values);
If anyone has better solution please post it.

INSERT INTO not working in IF block - T-SQL

im working on procedure which should transfer number of items (value #p_count) from old store to new store
SET #countOnOldStore = (SELECT "count" FROM ProductStore WHERE StoreId = #p_oldStoreId AND ProductId = #p_productID)
SET #countOnNewStore = (SELECT "count" FROM ProductStore WHERE StoreId = #p_newStoreID AND ProductId = #p_productID)
SET #ShiftedCount = #countOnOldStore - #p_count
SET #newStoreAfterShift = #countOnNewStore + #p_count
IF #ShiftedCount > 0
BEGIN
DELETE FROM ProductStore WHERE storeId = #p_oldStoreId and productID = #p_productID
INSERT INTO ProductStore (storeId,productId,"count") VALUES (#p_oldStoreId,#p_productID,#ShiftedCount)
DELETE FROM ProductStore WHERE storeId = #p_newStoreID and productID = #p_productID
INSERT INTO ProductStore (storeId,productId,"count") VALUES (#p_newStoreID,#p_productID,#newStoreAfterShift)
END
ELSE
PRINT 'ERROR'
well ... second insert is not working. I cant figure it out. It says
Cannot insert the value NULL into column 'count', table 'dbo.ProductStore'; column does not allow nulls. INSERT fails.
Can anyone see problem and explain it to me ? Its school project
It looks like your entire query should just be:
UPDATE ProductStore
SET [count] = [count] + CASE
WHEN storeId = #p_NewStoreID THEN #p_Count
ELSE -#p_Count END
WHERE
productID = #p_ProductID and
storeID in (#p_NewStoreID,#p_OldStoreID)
If either value in the following is NULL, the total will be NULL:
SET #newStoreAfterShift = #countOnNewStore + #p_count
Check both values (#countOnNewStore, #p_count) for NULL.
Looks like you are not assigning any value to #p_count, so it is NULL and so are #ShiftedCount and #newStoreAfterShift.

How can i change null value to "0" by CASE statement

i got stuck to change a null value to "0" i write a code like this
SELECT
Custom.tblR_docProducer.libtxtDocumentID AS ParentID,
Custom.tblR_docProducer_grdProductRating.grdProductName AS ProductName,
Custom.tblR_docProducer_grdProductRating.grdProductType AS CategoryID,
Custom.tblR_docProducer_grdProductRating.gdlkRating AS StarID,
Custom.tblR_docProducer_grdProductRating.gdlkRatingYear AS YearID,
1 AS DisplayOrder,
0 AS isDisabled
FROM Custom.tblR_docProducer
INNER JOIN Custom.tblR_docProducer_grdProductRating
ON Custom.tblR_docProducer.Id = Custom.tblR_docProducer_grdProductRating._Parent
A result is still null like this
StarID
5
NULL
Use IsNull
IsNull(Custom.tblR_docProducer_grdProductRating.gdlkRating, 0) AS StarID