I've a SELECT which checks a status of active alarms (icinga).
This select joins different tables and until here all ok.
On the result I've as value/column an object_id as well. I would like to add a column to that select that could be empty or not, because, searching that 'object_id' on a different table, I could get a value or not. This accessory table is structured having: object_id, varname, varvalue.
So, i.e., my SELECT returns those values:
`name`, `object_id`, `status`
`Hello`, `123456`, `OK`
I would add the column City that should compared to a table having:
`object_id`, `varname`, `varvalue`
`123456`, `city`, `Rome`
`123456`, `lake`, `Garda`
`789789`, `city`, `Milano`
So that if the second table has object_id = 123456 AND city = Rome the result should be:
`name`, `object_id`, `status`, `city`
`Hello`, `123456`, `OK`, `Rome`
Otherwise the result should be:
`Hello`, `123456`, `OK`, `UNKNOWN`
How to do that?
Hope I've explained it well :-)
Thanks!
* EDIT *
It's better I explain with real example. My query actually is the following:
select icinga_objects.object_id, icinga_objects.name1 as host_name, icinga_objects.name2 as ServiceName, "service" as Type, icinga_servicestatus.last_check as LastCheckTime, icinga_servicestatus.last_hard_state_change as LastStateChange, TIMEDIFF(now(), icinga_servicestatus.last_hard_state_change) AS SinceTime,
CASE
WHEN icinga_servicestatus.current_state = 0 THEN '0'
WHEN icinga_servicestatus.current_state = 1 THEN '2'
WHEN icinga_servicestatus.current_state = 2 THEN '3'
ELSE '3'
END AS state
FROM icinga_objects, icinga_servicestatus, icinga_services WHERE icinga_servicestatus.service_object_id IN
(SELECT service_object_id FROM icinga_services WHERE icinga_services.host_object_id IN
(SELECT host_object_id FROM icinga_hostgroup_members WHERE hostgroup_id IN
(SELECT hostgroup_id FROM icinga_hostgroups WHERE alias = 'MY-HOSTGROUP-TO-FILTER')
)
)
AND icinga_servicestatus.service_object_id NOT IN
(SELECT service_object_id FROM icinga_services WHERE icinga_services.service_object_id IN (
SELECT object_id FROM icinga_objects WHERE icinga_objects.is_active = 1 AND icinga_objects.object_id IN
(SELECT object_id FROM icinga_customvariables WHERE varvalue = '8x5')
)
)
AND icinga_servicestatus.last_check > NOW() - INTERVAL 3 HOUR
AND icinga_servicestatus.state_type = 1
AND icinga_servicestatus.scheduled_downtime_depth = 0
AND icinga_objects.object_id = icinga_services.service_object_id
AND icinga_servicestatus.service_object_id = icinga_services.service_object_id
AND icinga_servicestatus.current_state = 2
AND icinga_servicestatus.problem_has_been_acknowledged = 0
This gives me as result, in example:
`object_id`, `host_name`, `ServiceName`, `Type`, `LastCheckTime`, `LastStateChange`, `SinceTime`, `State`
`123456`, `myHostName`, `myServiceName`, `service`, `2020-04-29 17:19:21`, `2020-04-28 14:50:27`, `26:32:51`, `3`
Here I would like to add the column.
So, now if I search object_id into icinga_customvariables I could find entries, or not. In Example, searching object_id = 123456 I have 4 records, but ONLY one having varname = NAME_IM_SEARCHING and so I need to add to the above result the corresponding of varvalue searching icinga_customvariables.object_id = '123456' AND varname = NAME_IM_SEARCHING. IF there are NO results, then the added cloumn should be UNKNOWN, otherwise the added column should be = icinga_customvariables.varvalue.
How to add it? :-)
You can place your query into a "table expression" so it becomes simpler to join it to the other_table. For example:
select
q.*,
coalesce(o.varvalue, 'UNKNOWN') as city
from (
-- your existing query here
) q
left join other_table o on o.object_id = q.object_id and o.varname = 'city'
EDIT: Joining multiple times
As requested if you need to extract more city names using another column, or if you want to extract against another table altogether, you can add an extra LEFT JOIN. For example:
select
q.*,
coalesce(o.varvalue, 'UNKNOWN') as city,
coalesce(o2.varvalue, 'UNKNOWN') as lake
from (
-- your existing query here
) q
left join other_table o on o.object_id = q.object_id and o.varname = 'city'
left join other_table o2 on o.object_id = q.object_id and o2.varname = 'lake'
I'm doing a pretty complicated reporting function with many conditions, many panels,
I have a record in tbl_my_report
id param_filter
101 FIND_IN_SET(t.owner_department,'0620510200,0621510200,0623510200')
Query:
SELECT *
FROM tbl_abc t WHERE t.id = '1' AND
(SELECT mr.param_filter
FROM tbl_my_report mr WHERE mr.id = '101'
)
How to use it as a valid condition string?
First, you should normalize your data, and get rid of FIND_IN_SET. So, there should be some department table looking like this:
id | owner
'101' | '0620510200'
'101' | '0621510200'
'101' | '0623510200'
With this table in place, you may refactor your query to:
SELECT *
FROM tbl_abc t
WHERE
t.id = '1' AND
EXISTS (SELECT 1 FROM department WHERE id = '101' AND owner = t.owner_department);
In general, you should avoid storing CSV or other unnormalized data in your database tables, for the very reason that it can make querying difficult.
Use this:
SELECT * FROM tbl_abc t WHERE t.id = '1' IN (SELECT mr.param_filter
FROM tbl_my_report mr WHERE mr.id = '101' );
I'm bogged in trying to figure out why query a is returning different records than query b. Both queries have seemingly same purpose yet a is returning 500 and b 3500.
this is query a:
SELECT DISTINCT ODE.OrderBillToID
FROM APTIFY.dbo.vwVwOrderDetailsKGExtended ODE
WHERE ProductID IN (2022, 1393)
AND LTRIM(RTRIM(ODE.OrderStatus)) <> 'Cancelled'
AND LTRIM(RTRIM(ODE.OrderType)) <> 'Cancellation'
AND LTRIM(RTRIM(ODE.cancellationStatus)) <> 'FULLY CANCELLED'
UNION
SELECT DISTINCT ID
FROM APTIFY.dbo.vwPersons WHERE City = 'A'
UNION
SELECT DISTINCT RecordID
FROM APTIFY.dbo.vwTopicCodeLinks WHERE TopicCodeID = 16 AND Value = 'Yes, Please'
query b:
SELECT
APTIFY..vwPersons.ID
FROM
APTIFY..vwPersons
WHERE
( APTIFY..vwPersons.ID IN (
SELECT
vwMeetingRegistrants.ID
FROM
APTIFY.dbo.vwMeetings vwMeetings
INNER JOIN APTIFY.dbo.vwMeetingRegistrants vwMeetingRegistrants
ON vwMeetings.ID=vwMeetingRegistrants.ActualMeetingID WHERE
vwMeetings.ProductID = 2022
)
OR
APTIFY..vwPersons.ID IN (
SELECT
vwMeetingRegistrants.ID
FROM
APTIFY.dbo.vwMeetings vwMeetings
INNER JOIN APTIFY.dbo.vwMeetingRegistrants vwMeetingRegistrants
ON vwMeetings.ID=vwMeetingRegistrants.ActualMeetingID WHERE
vwMeetings.ProductID = 1393
)
OR
APTIFY..vwPersons.City = N'Albany' )
OR
((
APTIFY..vwPersons.ID IN (
SELECT
RecordID
FROM
APTIFY.dbo.vwTopicCodeLinks vwTopicCodeLinks
WHERE
vwTopicCodeLinks.TopicCodeID = 16
)
AND
APTIFY..vwPersons.ID IN (
SELECT
RecordID
FROM
APTIFY.dbo.vwTopicCodeLinks vwTopicCodeLinks
WHERE
vwTopicCodeLinks.Value = N'Yes, Please'
) )
)
vwMeetingsRegistrants from the b query are producing the same records as orderkgdetailsextended from query. I cannot see ANY difference in those queries - which perhaps shows my lack of understanding the query behaviour.
BIG Thanks for any points guys! :)
As it came out, incorrectly structured query is a result of badly configured application, Aptify.
I am confused here This first sql-
I have one entry in my cnt_content table with content_pk=5419441 and title=test wls-2
Now when I am running this sql 1-
SELECT
title,
content_pk
FROM
cnt_content c
WHERE
c.type not in (
'AMT', 'LPA', 'QUE'
)
AND c.private_flag = 'N'
AND c.searchable_flag = 'Y'
AND c.status in (
'PUB', 'NAP'
)
AND (
trim(c.title) LIKE 'test wls-2'
OR trim(c.special_keyword) LIKE 'test wls-2'
)
and not exists (
SELECT
1
FROM
cmd_content_metadata cmd
WHERE
cmd.content_pk=5419441
AND cmd.for_others='Y'
)
ORDER BY
c.last_modified_date desc;
it is giving result-content_pk=5419441 and title=test wls-2
But when I am running this sql 2-
SELECT
title,
content_pk
FROM
cnt_content c
WHERE
c.type not in (
'AMT', 'LPA', 'QUE'
)
AND c.private_flag = 'N'
AND c.searchable_flag = 'Y'
AND c.status in (
'PUB', 'NAP'
)
AND (
trim(c.title) LIKE 'test wls-2'
OR trim(c.special_keyword) LIKE 'test wls-2'
)
and not exists (
SELECT
1
FROM
cmd_content_metadata cmd
WHERE
cmd.content_pk=c.content_pk
AND cmd.for_others='Y'
)
ORDER BY
c.last_modified_date desc;
It is not giving any result. Anyone please explain.
Because in one you just giving specific value for content_pk as 5419441, while other one uses corelated query which means for each and every value of content_pk selected in outer query, you are checking for equality in your sub select query.
I hate 4000+ adverts on a database. I use a FULLTEXT index on fields title, model and description.
In MySQL I change the value of ft_min_word_len from 4 to 3.
Actually, all the results are not matched.
Here is a simple request :
SELECT * ,
MATCH (
anno_modele, anno_titre, anno_desc
)
AGAINST (
"330"
) AS relevance
FROM (
`annonce`
JOIN possede
USING ( `anno_id` )
JOIN annonceur
USING ( `ann_id` )
JOIN cat_lang
USING ( `cat_id` )
JOIN lang_pays
USING ( `pays_id` )
JOIN marque
USING ( `mar_id` )
WHERE `mar_id` =867
AND MATCH (
anno_modele, anno_titre, anno_desc
)
AGAINST (
" 330"
)
AND `cat_id`
IN (
'3'
)
AND `anno_active` =1
AND `anno_mode` =1
AND `lang_pays`.`lang_id` = '3'
GROUP BY `anno_id`
ORDER BY `anno_prix` , `relevance` DESC
LIMIT 15
This matches me 3 results. 330 is just the field "anno_model".
If if do a like anno_modele LIKE '%330%', it matches me 9 results.
Here are the results matched by MATCH AGAINST :
Here are the results matched by LIKE
As you can see, when it exists a space ... the results are not matched by MACTH AGAINST
Is the problem on my request or it's something else ?
Help me please =)
Try using the * wildcard
...AGAINST ('*330*') ...