I have relationships that might not necessarily exist (they could be optional i.e. null); for example, a image may not have an address so it may be null.
I am unsure how to not return all null values.
Is there some condition I can put in place on the join that says if the address is null don't do a join and don't return all the null columns?
SELECT im.title, im.alias_title, im.description, im.main_image, im.hits,
im.show_comment, im.created_on, im.date_taken, im.account_type_id,
c.make, c.model, ad.address_line_1, ad.address_line_2,
spc.state_province_county, tvc.town_village_city, co.country,
ge.latitude, ge.longitude, ge.zoom, ge.yaw, ge.pitch,
us.first_name, us.surname, us.user_set_online, ut.username,
ut.account_type_id, aty.`type`, ufy.realname, ufy.location,
ufy.location, ufy.account_type_id
FROM image im
INNER JOIN user us
ON im.user_id = us.id
LEFT JOIN user_type ut
ON us.id = ut.user_id
LEFT JOIN user_flickr_youtube ufy
ON ut.id = ufy.user_type_id
LEFT JOIN account_type aty
ON ut.account_type_id =aty.id
LEFT JOIN address ad
ON im.address_id = ad.id
LEFT JOIN state_province_county spc
ON ad.state_province_county_id = spc.id
LEFT JOIN town_village_city tvc
ON ad.town_village_city_id =tvc.id
LEFT JOIN country co
ON ad.country_id =co.id
LEFT JOIN geolocation ge
ON im.geolocation_id = ge.id
LEFT JOIN camera c
ON im.camera_id = c.id
WHERE im.alias_title = 'test'
AND im.approved = 'Yes'
AND im.visible = '1'
LIMIT 1;
Is there some condition i can put in place on the join that says if the address is null dont do a join and dont bring me back all the null columns
Yes; you can run a JOIN instead of a LEFT JOIN. But that won't simply exclude the address if it is NULL, it will ignore the whole row altogether.
Usually this kind of situation is either handled by supplying a default value, possibly empty, for example directly in MySQL
SELECT
...COALESCE(ad.address_line_1,'(no address)') AS address_line_1,
COALESCE(ad.address_line_2,'') AS address_line_2, ...
or it is handled by the application:
if row['address_line_1']:
result = result + ("<td class=\"address\">%s</td>" % ( row['address_line_1'] ))
...
This also because a query could potentially return not one record, but several, and of these, some might have a NULL colum and some might not.
UPDATE
There is a way, but it's likely to make milk go sour in cows fifty miles downrange.
This is a proof of concept, on a MUCH smaller query and table, and takes advantage of the possibility of dynamically building a query.
First of all we have our query WHERE condition, here represented by "id = 1". We want to have the name column if the name column is not NULL.
SELECT #address := COALESCE(MIN(',name'),'') FROM client WHERE name IS NOT NULL AND id = 1;
This will return an empty string if the selected column is NULL. Otherwise it will return a comma and the name of that column.
This is the statement that in your case will be humongous, given your query. It contains the same WHERE as before, without the request that the name be NULL. And the field list is now dynamic.
SELECT #string := CONCAT('SELECT id', #address, ' FROM client WHERE id = 1');
Except that #string is, well, a string. To execute it as a query we do
PREPARE query FROM #string;
EXECUTE query;
DEALLOCATE PREPARE query;
How this might interact with your application, I do not dare fathom. I have tried an implementation in PHP on an expendable VM :-), cycling between the values of 1 and 3 (one row has a NULL name, one hasn't).
<?php
// Connect to this VM's local DB
mysql_connect('localhost','root','') or die("Cannot connect");
mysql_select_db('test');
foreach(array(1, 3) as $id)
{
mysql_query("SELECT #address := COALESCE(MIN(',name'),'') FROM client WHERE name IS NOT NULL AND id = $id;");
mysql_query("SELECT #string := CONCAT('SELECT id', #address, ' FROM client WHERE id = ', $id);");
mysql_query("PREPARE query FROM #string;");
$exec = mysql_query("EXECUTE query;");
while($tuple = mysql_fetch_assoc($exec))
{
print implode(" | ", $tuple) . "\n";
}
mysql_query("DEALLOCATE PREPARE query;");
}
?>
The answer seems to indicate it's working:
1 | Rossi
3
(I wouldn't have been surprised if it returned something like 'Ia! Cthulhu fhtagn!').
Related
This is what I'm calling and passing from service:
List<String> projectOwners = filterComponent.getProjectOwner();
List<String> dataProviderCodes = filterComponent.getDataProvider();
custEnrollmentMgmts = customerEnrollmentManagementRepository.findActiveByPage(getArchiveDate(),
completedEnrollmentStatusCodes, projectOwners, dataProviderCodes, getNoSearchCriteria(projectOwners, dataProviderCodes), pageRequest);
This is the query:
select distinct a.*
from cust_enrollment_mgmt a
inner join cust_enrollment_rel_mgmt r
on a.cust_enrollment_proj_id=r.cust_enrollment_proj_id
left join cust_prime p
on p.cust_prime_id = r.cust_prime_id
where a.cust_enrollment_proj_id NOT IN
(
select ce.cust_enrollment_proj_id
from cust_enrollment_mgmt ce
inner join enrollment_status_avt es
on ce.enrollment_status_id = es.enrollment_status_id
where ce.sys_update_ts < "2022-06-06 00:00:00"
and es.enrollment_status_desc in ("Complete", "Inactive")
)
and
(
if ((:code) is not null and (:name) is not null ,
a.data_provider_cd in (:code) and p.cust_prime_nm in (:name),0)
or
if ((:code) is not null and (:name) is null , a.data_provider_cd in (:code),0)
or
if ((:code) is null and (:name) is not null , p.cust_prime_nm in (:name),0)
or 1=:nosearchcriteria
);
If and only if the dataProviderCodes or projectOwners is not empty
then only it should go to that where condition.
If I pass dataProviderCodes and pass projectOwners then it should
fetch only projectOwner data If I'm not passing anything then it has
to stop ("Complete", "Inactive") and fetch up to that.
After that ("Complete", "Inactive") I need to fetch as per this
condition ☝☝☝.
The main thing is that it has to fetch only if data is present for the param we are passing.
This is working but if I pass more than 1 data It fails because I'm passing a list it may contain 1 or more than 1 or empty. For example: for dataProviderCodes if I pass ["aa","bb"] it fails.
I need to perform fetching if and only if the values are not null or present.
The whole implementation is regarding filtering.
I am having issues pulling in null values in my query. I am looking for patients who have a specific document name in their chart but also want to show patients who do not have this specific document name as well. Right now my code is only pulling in the patients with the document name History and Physical (Transcription) but I need to see Null values as well. Below is my code:
snip of code
SELECT CV3ClientVisit.ClientDisplayName, CV3ClientVisit.CurrentLocation, CV3ClientVisit.IDCode, CV3ClientVisit.VisitIDCode, CV3ClientVisit.VisitStatus, CV3ClientVisit.TypeCode, CV3ClientDocumentCUR.DocumentName
FROM CV3ClientVisit INNER JOIN
CV3ClientDocumentCUR ON CV3ClientVisit.GUID = CV3ClientDocumentCUR.ClientVisitGUID
WHERE (CV3ClientVisit.VisitStatus = 'ADM') AND (CV3ClientVisit.TypeCode = 'INPATIENT ADMIT') AND (CV3ClientDocumentCUR.DocumentName = 'History & Physical (transcription)' OR CV3ClientDocumentCUR.DocumentName IS NULL )
Use a LEFT JOIN with the condition in the ON clause:
SELECT cv.ClientDisplayName, cv.CurrentLocation, cv.IDCode,
cv.VisitIDCode, cv.VisitStatus, cv.TypeCode, cd.DocumentName
FROM CV3ClientVisit cv LEFT JOIN
CV3ClientDocumentCUR cd
ON cv.GUID = cd.ClientVisitGUID AND
cd.DocumentName = 'History & Physical (transcription)'
WHERE cv.VisitStatus = 'ADM' AND
cv.TypeCode = 'INPATIENT ADMIT' ;
I also added table aliases to simplify the query.
SQL Query
sessionFactory.getCurrentSession().createSQLQuery("select claim.encounterId, claim.claimUniqID, patientmaster.FirstName, tbl_insurance.insurance_name, claim.status from rcmdb.claim join rcmdb.encounter on claim.encounterID=encounter.encounterID join rcmdb.insurance_details on encounter.insuranceDetailsID=insurance_details.insuranceDetailsID
join rcmdb.tbl_insurance on insurance_details.insurance=tbl_insurance.insurance_id
join rcmdb.patientmaster onpatientmaster.patientMasterID=encounter.patientMasterID
where createdByDate between'"+from+"' and '"+to+"'").list();
i want to return string values based on claim.status values like if the status is 1 accepted, in output I want the string values how can I write the query?
You can use CASE statement. https://www.w3schools.com/sql/func_mysql_case.asp
SELECT CASE
WHEN status =1 THEN STRING
ELSE NULL
END
Put a table in the database that maps the int to the string and join it:
ClaimStatus
--------------
ID, StatusDescription
1, Accepted
2, Rejected
SELECT c.PolicyNumber, c.ClaimValue, cs.StatusDescription
FROM
claims c
INNER JOIN claimstatus cs ON c.ClaimStatusId = cs.ID
I am not so into SQL and I have the following problem woring on a MySql query. I try to explain you what I have to do.
I have this query, it works fine:
SELECT
LNG.id AS language_id,
LNG.language_name AS language_name,
LNG.language_code AS language_code,
CLP.is_default AS id_default_language
FROM Country_Language_Preference AS CLP
INNER JOIN Country AS CNT
ON CLP.country_id = CNT.id
INNER JOIN Languages AS LNG
ON CLP.language_id = LNG.id
WHERE
CNT.country_name = "Senegal"
This query have a single WHERE input parameter, this:
CNT.country_name = "Senegal"
I want to implement the following behavior: if the passed parameter have value Senegal or Rwanda perform the previous query.
If this input parameter have a different value form Senegal or Rwanda perform the same query but using this WHERE condition_
CNT.country_name = "GLOBAL"
Can I do something like this using SQL?
Using CASE Statement, this should be possible.
Try this:
SELECT
LNG.id AS language_id,
LNG.language_name AS language_name,
LNG.language_code AS language_code,
CLP.is_default AS id_default_language
FROM Country_Language_Preference AS CLP
INNER JOIN Country AS CNT
ON CLP.country_id = CNT.id
INNER JOIN Languages AS LNG
ON CLP.language_id = LNG.id
WHERE
CNT.country_name = CASE WHEN #Country = "Senegal" OR #Country = "Rwanda" THEN "Senegal"
ELSE "GLOBAL" END
Simply use OR:
WHERE (CNT.country_name = #country OR #country = 'GLOBAL')
#country is whatever parameter you are passing in.
If you want to limit to those two countries, then:
WHERE (CNT.country_name = #country OR
(#country NOT IN ('Rwanda', 'Senegal') AND CNT.country_name = 'GLOBAL')
)
But the first version seems more versatile.
i have a stored procedure in mysql with a couple of queries and i need to perform some operations with that query.
This is some the code from the stored procedure:
BEGIN
SET ##session.collation_connection = ##global.collation_connection;
DROP TEMPORARY TABLE IF EXISTS innerContainers;
CREATE TEMPORARY TABLE `innerContainers` (
`id_container` INT(10) NOT NULL,
`display_name` VARCHAR(100) NOT NULL,
PRIMARY KEY (`id_container`)
)
ENGINE = memory;
INSERT INTO innerContainers(id_container, display_name)
(SELECT c1.id_container, c1.display_name
FROM container_presentation cp
LEFT JOIN presentation p USING(id_presentation)
LEFT JOIN container c1 ON p.id_container = c1.id_container
WHERE c1.isDeleted = 0 AND c1.isActive = 1 AND
cp.id_container = in_id_container)
UNION
(SELECT c1.id_container, c1.display_name
FROM container_assembly_item cp
LEFT JOIN presentation p USING(id_presentation)
LEFT JOIN container c1 ON p.id_container = c1.id_container
WHERE c1.isDeleted = 0 AND c1.isActive = 1 AND
cp.id_container = in_id_container);
SELECT mad.id_container,
mat.sign_stock,
ma.id_management_start_point,
ma.id_management_end_point,
mad.quantity
FROM management_activity ma
LEFT JOIN management_activity_type mat ON ma.id_management_activity_type = mat.id_management_activity_type
LEFT JOIN management_activity_detail mad ON ma.id_management_activity = mad.id_management_activity
LEFT JOIN management_stock_point msp ON ma.id_management_end_point = msp.id_management_stock_point
LEFT JOIN management_stock_point msp1 ON ma.id_management_start_point = msp1.id_management_stock_point
WHERE mad.id_container IN (SELECT id_container FROM innerContainers)
ORDER BY mad.id_container ASC;
END
Now, after the last query.. i need to do some operations and return a value for each id_container inside the temporary table depending on the values in the second query.
Something like this:
foreach id_container in the second query i have a resultValue and i need to:
if the sign_stock == 1 and some other conditions then resultValue -= quantity and if sign_stock == 2 and some other conditions then resultValue += quantity.
And the final resultValue after iterating over the id_container lines will be the one i want for that id_container in the temporary table.
I dont know how to do that operation.. can some one help me with that?
Don't create a temporary table unless you need the data after the procedure call. Either way, in order to iterate over the results of a SELECT query, use a CURSOR.
A simple example is provided in the linked manual page.