MySQL Query if else JOIN - mysql

SELECT * FROM bn_garant_tpl
JOIN bn_garant_val
WHERE bn_garant_tpl.what_tpl IN (1, 2)
AND bn_garant_tpl.id_tpl = bn_garant_val.id_garant_tpl
ORDER BY ords ASC
how to get lines where what_tpl = 1?
problem is next: in table bn_garant_val not exist lines if what_tpl = 1. just for if what_tpl = 2.
this query return if ID's match
AND bn_garant_tpl.id_tpl = bn_garant_val.id_garant_tpl
but, in result must be: if what_tpl = 1 also

If you need records from bn_garant_tpl even if no such record in bn_garant_val, use LEFT JOIN:
SELECT * FROM bn_garant_tpl
LEFT JOIN bn_garant_val ON bn_garant_tpl.id_tpl = bn_garant_val.id_garant_tpl
WHERE bn_garant_tpl.what_tpl IN (1, 2)
ORDER BY ords ASC

Related

"Duplicate column name" error that shouldn't exist

I'm trying to migrate a database from sqlite to mariaDB ( which I never worked with ) and I can't seem to get past this problem!
When I try to run this, I always get
"#1060 - Duplicate column name 'id_document'"
Here's the query:
SELECT
a.id_document AS id_document,
id_user_associatedDoc,
id_user_creator,
stage,
title,
goldStandardAnnotationManual,
count(content) AS answer_count
FROM
(SELECT *
FROM Document join DocumentProject
ON Document.id_document = DocumentProject.id_document
WHERE DocumentProject.id_project = 2) a
LEFT JOIN
(SELECT *
FROM Annotation
WHERE Annotation.id_project = 2) b
ON a.id_document = b.id_document
GROUP BY a.id_document;
I don't understand why I should be getting this error! Can you help?
This first subquery syntax returns two id_document column:
(SELECT *
FROM Document
join DocumentProject
ON Document.id_document = DocumentProject.id_document
WHERE DocumentProject.id_project = 2) a
A quick way to fix this:
SELECT
a.id_doc /*Change this column as following*/ AS id_document,
id_user_associatedDoc,
id_user_creator,
stage,
title,
goldStandardAnnotationManual,
count(content) AS answer_count
FROM
(SELECT *, Document.id_document as "id_doc" /*define the first id_document column as a different name*/
FROM Document
join DocumentProject
ON Document.id_document = DocumentProject.id_document
WHERE DocumentProject.id_project = 2) a
LEFT JOIN
(SELECT *
FROM Annotation
WHERE Annotation.id_project = 2) b
ON a.id_document = b.id_document
GROUP BY a.id_document;
You can also pre-define which column you want to return inside the subquery as well. Example:
(SELECT Document.id_document, Document.column_2, Document.column_3
FROM Document
join DocumentProject
ON Document.id_document = DocumentProject.id_document
WHERE DocumentProject.id_project = 2) a
That way, your outer query should select the a.id_document according to what you have pre-define inside the subquery and no need to change anything from the outer query.

SQL error as a result of rewriting a query using subquery into a query using join

The original query:
SELECT o.offering_number,
o.english_description,
o.french_description,
fop.price_amount,
fop.price_type_code,
fop.price_status_code,
fop.offering_id,
(SELECT fop1.price_amount from facility_offering_price fop1
WHERE fop.offering_id = fop1.Offering_Id
AND fop1.price_type_code = 5
AND fop1.price_status_code = 3
) as 'priceAmount'
from facility_offering_price fop
join offering o on fop.offering_id = o.offering_id
WHERE fop.price_start_date = '15-10-28'
AND fop.price_status_code IN (1,2)
/*AND (price_status_code IS NULL)*/
AND fop.price_type_code = 5
/*AND (o.offering_number IS NULL)*/
ORDER BY o.offering_number ASC, fop.price_sequence_number ASC;
It produces a result of one entry.
The result query:
SELECT o.offering_number,
o.english_description,
o.french_description,
fop.price_amount,
fop2.price_amount,
fop.price_type_code,
fop.offering_id,
fop2.offering_id
from facility_offering_price fop
join offering o on fop.offering_id = o.offering_id
inner join
(select
fop1.offering_id,
fop1.price_amount
from facility_offering_price fop1
WHERE fop1.price_type_code = 5
AND fop1.price_status_code = 3
) fop2 on fop.offering_id = fop2.offering_id
WHERE fop.price_start_date = '15-10-28'
AND fop.price_status_code IN (1,2)
/*AND (price_status_code IS NULL)*/
AND fop.price_type_code = 5
/*AND (o.offering_number IS NULL)*/
ORDER BY o.offering_number ASC, fop.price_sequence_number ASC;
It's result set is empty. However, an entry is found if I ask for fop1.price_status_code = 1.
Unable to wrap my head around this one I would appreciate your help.
Try using LEFT JOIN instead. The conversion from SELECT a, subquery AS val FROM ... to a join is more accurately reflected that way. The original query would return rows with NULL val when the subquery has no results; your version ends up omitting such rows completely.

return rows with specific tag

I have 3 tables
listings
listtags
listing_listtag
listing can have multiple tags assigned to it and those are stored in listing_listtag with forein keys to listings and listtags table
I have a problem to select only a listing which has 2 tags associated with it.
I have this query:
select *
from `listtags`
inner join `listing_listtag` on `listtags`.`id` = `listing_listtag`.`tag_id`
where `listing_listtag`.`listing_id` = 5
and `slug` = "delivery"
AND slug = "wireless-internet"
and it returns nothing. if I chnage the last AND to OR it now returns
I would like the query to only return one row where listing_id is 5, how can I do this?
Here is one method:
select ?.listing_id
from listtags lt inner join
listing_listtag llt
on lt.id = llt.tag_id
where llt.listing_id = 5 and
?.slug in ('delivery', 'wireless-internet')
group by ?.listing_id
having count(*) = 2;
The ? is for the table alias of the table with the column.
Note: If the data can have duplicates, use count(distinct slug).
You just need a pair of brackets:
select *
from `listtags`
inner join `listing_listtag` on `listtags`.`id` = `listing_listtag`.`tag_id`
where `listing_listtag`.`listing_id` = 5
and (`slug` = "delivery"
or slug = "wireless-internet")

Incorrect SUM when using two LEFT JOINs and a GROUP BY

The following code returns an incorrect value for the sumHours field. It appears to prepare the sumHours field then once the GROUP BY runs, sum the sums together.
SELECT mmr_ID, mmr_projectName, SUM(mmr_hoursWorked.mmr_hoursWorked_hours) AS sumHours
FROM mmr
LEFT JOIN mmr_hoursWorked
ON mmr.mmr_ID = mmr_hoursWorked.mmr_hoursWorked_project AND mmr_hoursWorked.mmr_hoursWorked_mm = "P90826"
LEFT JOIN mmr_notes
ON mmr.mmr_ID = mmr_notes.mmr_notes_MMR_ref AND mmr_notes.mmr_notes_author = "P90826"
WHERE mmr_mmAssigned = "P90826" AND mmr_projectStatus != 1 OR mmr_notes.mmr_notes_author = "P90826" AND mmr_projectStatus != 1
GROUP BY mmr_ID
Actual Results
mmr_ID - 35
mmr_projectName - Project A
sumHours - 140.2
Expected Results
mmr_ID - 35
mmr_projectName - Project A
sumHours - 35.05
Due to JOIN statements combination of results are returned, so you should handle aggregates and joins separately. Try this:
SELECT t.*
FROM
(
SELECT mmr_ID, mmr_projectName, SUM(mmr_hoursWorked.mmr_hoursWorked_hours) AS sumHours
FROM mmr
LEFT JOIN mmr_hoursWorked
ON mmr.mmr_ID = mmr_hoursWorked.mmr_hoursWorked_project AND mmr_hoursWorked.mmr_hoursWorked_mm = 'P90826'
WHERE mmr_projectStatus != 1 AND mmr_mmAssigned = 'P90826'
GROUP BY mmr_ID, mmr_projectName, mmr_mmAssigned
) t
LEFT JOIN mmr_notes
ON t.mmr_ID = mmr_notes.mmr_notes_MMR_ref
WHERE mmr_notes.mmr_notes_author = 'P90826';
The issue was corrected by normalizing the database. The mmr_notes table was integrated into the mmr_hoursWorked table since it only had one unique field.

MYSQL - BASIC QUERYS where + group by + having

SELECT dieet.snr, soort.nsnaam FROM soort
JOIN dieet ON soort.snr = dieet.snr
JOIN voedsel ON dieet.voednr = voedsel.voednr
WHERE voedsel.voednr = 22
GROUP BY dieet.snr
HAVING COUNT(*) = 1 ;
the where condition messes up my output, what am i doing wrong
I suspect that you are looking for "snr"s that have exactly one record that is a "voednr = 22". Your query is getting all "snr"s that have exactly one such "voednr", along with other "voednr"s.
Let me suggest the following query:
SELECT dieet.snr, soort.nsnaam
FROM soort
JOIN dieet ON soort.snr = dieet.snr
JOIN voedsel ON dieet.voednr = voedsel.voednr
GROUP BY dieet.snr
HAVING COUNT(*) = 1 and max(voedsel.voednr) = 22
This will get you the rows with the one and only 22.