MYSQL Selecting specific rows or first row if doesn't exist - mysql

I have a table of texts from various dates. Each is indexed by service, variation, and page and sub-page ids.
I need to fetch all entries for a given service, page and sub-page. i.e. each variation! BUT If the particular specific subpage doesn't exist, I need it to fetch the first subpage for that page, rather than nothing for that variation.
This is my code -
SELECT * FROM frames f
LEFT JOIN varients v ON f.varient_id = v.varient_id AND f.service_id = v.service_id
ẀHERE f.service_id = :sid
AND f.frame_id = :fid
AND (f.subframe_id = :subid
OR f.subframe_id = (
select min(subframe_id) from frames ff
ẀHERE ff.service_id = f.service_id
AND ff.varient_id = f.varient_id AND ff.frame_id = f.frame_id
)
)
GROUP BY f.service_id, f.varient_id, f.frame_id
ORDER BY f.service_id, v.varient_date, f.frame_id, f.subframe_id
but as often as not this just gives the minimum rather than the specific, even when the specific value exists. I'm pretty sure that the OR isn't what I need..
I've tried working with UNION as per some other answers, but since I want more than a single result, I can't seem to work it out!
Thanks for any help ..

OK. I managed to achieve what I wanted. Two days of messing with this, and finally work it out after posting a question. I was helped by one of the 'related' questions, which whilst not giving me an answer, made me think about it a different way -
I basically turned the whole thing inside out: As i only wanted one result per variation, I used that as the primary table. Then Joined the 'frames' table twice, once for the specific value, and once for the first value (found using a search for MIN().) Used IFNULL to return the second record if the first wasn;t found. An extra IS NOT NULL check against the second record within the WHERE to avoid returning anything where there is nothing stored against the variation record.
SELECT v.service_id, v.varient_id, IFNULL(f.frame_id,ff.frame_id)as frame_id,
IFNULL(f.subframe_id,ff.subframe_id) as subframe_id , IFNULL(f.frameunique, ff.frameunique) as frameunique, IFNULL(f.frame_content,ff.frame_content) as framecontent
FROM varients v
LEFT JOIN `frames` f ON `f`.`varient_id` = `v`.`varient_id` AND `f`.`service_id` = `v`.`service_id` AND `f`.`frame_id` = 698 AND `f`.`subframe_id` = 0004
LEFT JOIN `frames` ff ON `ff`.`varient_id` = `v`.`varient_id` AND `ff`.`service_id` = `v`.`service_id` AND `ff`.`frame_id` = 698
AND `ff`.`subframe_id` = (select min(`subframe_id`) from `frames` `fff` where `fff`.`service_id` = `v`.`service_id`
AND `fff`.`varient_id` = `v`.`varient_id` AND `fff`.`frame_id` = 698 )
where `v`.`service_id` = 3 AND ff.frameunique IS NOT NULL
ORDER BY `f`.`service_id`, `v`.`varient_date`, `f`.`frame_id`, `f`.`subframe_id`
Posting this in case it helps anybody else. It still needs tidying but it works. Thanks for the comments. :)

Related

How to query for something that doesn't exist?

I am trying to query a sample database to look for sites without a domain.
We know which site a domain is associated with by domains.site = sites.id. There is no similar variable from site to domain.
So, I tried this (and a couple other joins / where filtering). Either, it's outputting about 50x the number of actual number of entries for either table, or it's outputting nothing. (This one's the former)
SELECT sites.name, domains.domain FROM sites
INNER JOIN domains
ON sites.id != domains.site
WHERE sites.is_deleted = 0 AND sites.id != domains.site
And this one's an example the latter, which outputs nothing
SELECT sites.name, domains.domain FROM sites
LEFT JOIN domains
ON sites.id != domains.site
WHERE sites.is_deleted = 0 AND site = NULL
I'm clearly missing something, to be able to go through the combinations, where only the site name and NULL are outputted (due to there being no domains associated with the site).
Of course, it could be a trick question, and there are simply no sites without domains.
For your kind of query you need to start with the query that should work if the data existed, using a LEFT JOIN, then add the condition that the data don't exist. So:
SELECT sites.name, domains.domain FROM sites
LEFT JOIN domains
ON sites.id = domains.site /* <--- this is where you got it wrong */
WHERE sites.is_deleted = 0
AND domains.site IS NULL;

Listbox is not able to show items based on another list

I am currently trying to set up a GUI frontend for easier querying for colleagues.
I have tried researching and following instructions from various sources but still not able to make it work.
I have two lists.
1) This is the row source query for the first list(List0):
SELECT Test_Case_ID.Test_Case_Unique_ID, Test_Case_ID.Test_Case_Description
FROM Test_Case_ID
ORDER BY Test_Case_ID.[Test_Case_Description];
2) This is for the second list(List2):
SELECT Reference_ID.Reference
FROM Test_Case_ID INNER JOIN (Reference_ID INNER JOIN Test_Result
ON Reference_ID.Reference_Unique_ID = Test_Result.Reference_Unique_ID)
ON Test_Case_ID.Test_Case_Unique_ID = Test_Result.Test_Case_Unique_ID
WHERE (((Test_Case_ID.Test_Case_Description)=[Forms]![Form1]![List0]));
I have a an event procedure for List0:
Private Sub List0_AfterUpdate()
Forms![Form1]![List2].Requery
End Sub
However, there are no outputs on List2 even after clicking on items in List0. Can I have some advice to fix it? Thank you
Firstly, check that the bound column of your list box List0 corresponds to your Test_Case_Description field.
With the form open and populated with data, you can also run a number of tests 'manually' by creating a separate query containing the SQL for your list box row source and verifying whether or not it returns any results:
select
reference_id.reference
from
test_case_id inner join
(
reference_id inner join test_result
on reference_id.reference_unique_id = test_result.reference_unique_id
)
on test_case_id.test_case_unique_id = test_result.test_case_unique_id
where
test_case_id.test_case_description = [forms]![form1]![list0]
You can also use a query with the following SQL code to test the value returned by [forms]![form1]![list0] and ensure that it returns the value that you expect for use in your selection criteria:
select
t.test_case_description,
[forms]![form1]![list0] as listboxvalue,
t.test_case_description = [forms]![form1]![list0] as testmatch
from
test_case_id t

Access 'No Records Found' when Records Exist

I have a form in Access 2010 that's used as a search form to filter records matching specific criteria.
I transferred information in the backend from one set of tables to another. Now, the filter doesn't work. Even if I leave all the criteria blank - ie. set it to bring up all records - it tells me, 'No records found.'
I've remapped the tables a few times, made sure they all have information, and are linking and opening properly. What could be preventing Access from finding the records?
Here's the filter query, if it helps any. It doesn't appear to be filtering properly, even though it works fine with the old tables.
SELECT Activity.*, ActivityCash.*, EngSchDates.*, Monitoring.*, Procurement.*,
LookupDistrict.*
FROM ((((Activity LEFT JOIN LookupDistrict ON Activity.District =
LookupDistrict.District) INNER JOIN ActivityCash ON Activity.GWP = ActivityCash.GWP)
INNER JOIN EngSchDates ON Activity.GWP = EngSchDates.GWP)
INNER JOIN Procurement ON Activity.GWP = Procurement.GWP) INNER JOIN Monitoring ON
Activity.GWP = Monitoring.GWP ORDER BY Activity.District,
Activity.[ProgramYear], [Activity].GWP;
In general, to debug these types of problems, try removing one table at a time from the FROM clause (and SELECT) until you get your results back.
Remove AND [Activity].[Designer] like '*' from the query.

Select all elements from a table, and check if they match to another table

I have two tables, and I want to take all entities from the first table, then, check if they can be related to a specific entity from another table. If they can be related the database returns 1 (or true), else it returns NULL (or false).
I tried some things with LEFT JOIN but none of them work. I think the solution is simple but I can't figure it out...
Context : In my application I make two requests, the first one take all entities from oneTable, the second one take all idOT from anotherTable where idAT is equal to 2, THEN, I make a loop where I save all entities from the first request and in this loop I make another loop where I check if the current element is present on the second request. I thought they this solution was to heavy (two requests and imbricated loops) so I tried to do it directly in one request.
Thank you for your help guys ! I hope it won't make you lose your time...
Edit : #Strawberry gave me the answer in the comments, I was doing
SELECT * FROM oneTable LEFT JOIN anotherTable ON oneTable.idOT = anotherTable.idOT **WHERE** anotherTable.idAT = 2
instead of
SELECT * FROM oneTable LEFT JOIN anotherTable ON oneTable.idOT = anotherTable.idOT **AND** anotherTable.idAT = 2
It's as simple as that... Thank you again guys.
Thank to the comments of the question the correct request is :
SELECT * FROM oneTable
LEFT JOIN anotherTable ON oneTable.idOT = anotherTable.idOT
AND anotherTable.idAT = 2;

Multiple databases, possibly creating a loop?

I have the following code below...the query works, but I'm looking for a better way to search though an entire column for a specific criteria. I think my question is going to require a loop, I'm just not sure how to perform it.
The last line of code states '
Where [dbIdwWhseLC].[dbo].[tbItemTxt].[sTxt] like '%258912.pdf
The value 258912.pdf is the value in
[IDEAUrlBot].[dbo].[IDEA Project Tracker].[Filename]
I would like to try and create a method where the query reads one value in sTxt, then compares the whole column to Filename. If it finds the value, then display sTxt, if not, go to the next value in sTxt and begin searching each value in Filename.
Please let me know if you need additional information. Thanks in advance.
Select [dbIdwWhseLC].[dbo].[tbItemTxt].[nItemId]
, [sTxtType]
, [IDEAUrlBot].[dbo].[tbl_IDWItems].[nUrlId]
, [IDEAUrlBot].[dbo].[tbl_Urls].[sUrl]
, [sTxt]
, [Filename]
, [dbIdwWhseLC].[dbo].[tbItemTxt].[vUpdateDt]
From [dbIdwWhseLC].[dbo].[tbItemTxt]
Left Join [IDEAUrlBot].[dbo].[tbl_IDWItems] on [dbIdwWhseLC].[dbo].[tbItemTxt].[nItemid] = [IDEAUrlBot].[dbo].[tbl_IDWItems].[nItemid]
Join [IDEAUrlBot].[dbo].[tbl_Urls] on [IDEAUrlBot].[dbo].[tbl_IDWItems].[nUrlId] = [IDEAUrlBot].[dbo].[tbl_Urls].[nUrlId]
Join [IDEAUrlBot].[dbo].[IDEA Project Tracker] on [IDEAUrlBot].[dbo].[tbl_IDWItems].[nUrlId] = [IDEAUrlBot].[dbo].[IDEA Project Tracker].[UrlId]
Where [dbIdwWhseLC].[dbo].[tbItemTxt].[sTxt] like '%258912.pdf'
If I understand you correctly, it ought to be possible to do this:
select itemTxt.[nItemId]
, [sTxtType]
, idwItems.[nUrlId]
, urls.[sUrl]
, [sTxt]
, [Filename]
, itemTxt.[vUpdateDt]
From [dbIdwWhseLC].[dbo].[tbItemTxt] as itemTxt
Left Join [IDEAUrlBot].[dbo].[tbl_IDWItems] as idwItems
on itemTxt.[nItemid] = idwitems.[nItemid]
Join [IDEAUrlBot].[dbo].[tbl_Urls] as urls
on idwItems.[nUrlId] = urls.[nUrlId]
Join [IDEAUrlBot].[dbo].[IDEA Project Tracker] projTracker
on itemText.[nUrlId] = projTracker.[UrlId]
Where itemTxt.[sTxt] like '%258912.pdf' -- not sure you intend this to remain
and projTracker.[FileName] = itemTxt.[sTxt]
But that's so simple that there must be some aspect to what you're looking for that's not clear to me.
Do you want to stop searching after you find a match between [FileName] and [sTxt]? If you want to return exactly one record, you can just change the first line to
select top 1 itemTxt.[nItemId]
... and add an ORDER BY clause to the end to control how the results are sorted and therefore which one is the "top 1".
Do you need to use wildcards when matching [FileName] and [sTxt]? It's not clear to me from the description which column would have the full path (or file name) and which would have just "258912.pdf", but you could change my last line to:
itemTxt.[sTxt] like ('%' + projTracker.[FileName])
If you need something more complex, like the first record from itemTxt.[sTxt] that matches projTracker.[FileName] for every record in projTracker, please say so in the comments.
If none of this is along the lines of what you need, you'll need to elaborate on what it is you do need. Please add more detail to your question, such as an example of what the output should look like or what you plan to do with it.