SQL Access 2007/2010 Selecting Max Date with Distinct ID - sql

I believe a lot of people have already asked this question as I have read all the topic from here. But the Problem is I have 3 related tables instead of 2 and I'm not sure how to code for that
I have a table: tbl_Instruments, tbl_Record and tbl_Cal_By.
tbl_Instruments has all the instruments information including their ID.
tbl_Cal_By has the information for whoever is calibrating the tool.
tbl_Records has all the instruments Records and their Calibration date. It inherits the ID from tbl_Instruments as Inst_ID and the Name from tbl_Cal_By as Name_ABBR.
tbl_Instruments: ID, Type
tbl_Cal_By: Cal_ID, Name_ABBR
tbl_Records: Record_ID, Inst_ID, Cal_Date, Name_ABBR
Here is my code.
SELECT tbl_Records.Inst_ID
,tbl_Instruments.Type
,Max(tbl_Records.Cal_Date) AS MaxOfCal_Date
,tbl_Cal_By.Name_ABBR
FROM tbl_Cal_By
RIGHT JOIN (
tbl_Instruments INNER JOIN tbl_Records ON tbl_Instruments.ID = tbl_Records.Inst_ID
) ON tbl_Cal_By.ID = tbl_Records.BY
GROUP BY tbl_Records.Inst_ID
,tbl_Instruments.Type
,tbl_Cal_By.Name_ABBR;
Desired result:
Any help will be appreciated!

You can do this in several methods, one of the is exists :
SELECT tbl_Records.Inst_ID
,tbl_Instruments.Type
,tbl_Records.Cal_Date AS MaxOfCal_Date
,tbl_Cal_By.Name_ABBR
FROM tbl_Cal_By
RIGHT JOIN (
tbl_Instruments INNER JOIN tbl_Records ON tbl_Instruments.ID = tbl_Records.Inst_ID
) ON tbl_Cal_By.ID = tbl_Records.BY
WHERE NOT EXISTS(SELECT 1 FROM tbl_Records t
WHERE t.Inst_ID = tbl_Instruments.ID
AND t.Cal_date > tbl_Records.Cal_Date)
I'm not entirely sure about access syntax and aliases.. so maybe you will have to adjust it a little bit - like alias the first tbl_records so it will recognize it, or maybe it will work..

Related

how to do if query in postgres

I want to make a query in which if the query does not find records for the query not exist, then it looks to see if these codes are present in the array field. The join will go through the code c_oplmlp/c_serv
select distinct ocf.code_head_mo , cs.c_oplmp, r."name", ocf.code_state, rm2.name_short,
ocf.id_condition_mc
from puomp.op_registry r
join puomp.op_case_finish ocf on r.id_registry =ocf.id_registry
join puomp.op_patient pt on ocf.id_patient =pt.id_patient
join puomp.op_case sl on ocf.id_case_finish =sl.id_case_finish
join puomp.op_case_ext cs on sl.id_case =cs.id_case
left join nsi.ref_mo rm2 on r.id_head_mo =rm2.id_mo
where not exists(select * from lic_app_new lm
left join ksg_p kp
where
lm.fc_mo=ocf.code_head_mo
and (lm.c_serv =cs.c_oplmp) if( (lm.c_serv !=cs.c_oplmp) then
lm.c_serv=kp.smj_prof )
endif;
)
ksg_p table look like this
ksg_p
|---id
|---name
|---c_prof(same as c_serv)(main code)
|---smj_prof(related to c_prof)
The idea is if query does not find by main code(c_serv) it search by related codes. This is codes of illneses. Smj_prof contains related codes of illness code. For example ucler has a code of 3( witch is code of gastroenterology) and it has related codes of 9(therapy) and 10(pediatrics). It means that pacient can be treated in gastroenterology, therapy and pediatrics
Help pls i dont even had an idea of how to do this.
What if you need just add public. to SELECT options
example:
select distinct public.ocf.code_head_mo, public.cs.c_oplmp, ...etc...

SQL - Returning fields based on where clause then joining same table to return max value?

I have a table named Ticket Numbers, which (for this example) contain the columns:
Ticket_Number
Assigned_Group
Assigned_Group_Sequence_No
Reported_Date
Each ticket number could contain 4 rows, depending on how many times the ticket changed assigned groups. Some of these rows could contain an assigned group of "Desktop Support," but some may not. Here is an example:
Example of raw data
What I am trying to accomplish is to get the an output that contains any ticket numbers that contain 'Desktop Support', but also the assigned group of the max sequence number. Here is what I am trying to accomplish with SQL:
Queried Data
I'm trying to use SQL with the following query but have no clue what I'm doing wrong:
select ih.incident_number,ih.assigned_group, incident_history2.maxseq, incident_history2.assigned_group
from incident_history_public as ih
left join
(
select max(assigned_group_seq_no) maxseq, incident_number, assigned_group
from incident_history_public
group by incident_number, assigned_group
) incident_history2
on ih.incident_number = incident_history2.incident_number
and ih.assigned_group_seq_no = incident_history2.maxseq
where ih.ASSIGNED_GROUP LIKE '%DS%'
Does anyone know what I am doing wrong?
You might want to create a proper alias for incident_history. e.g.
from incident_history as incident_history1
and
on incident_history1.ticket_number = incident_history2.ticket_number
and incident_history1.assigned_group_seq_no = incident_history2.maxseq
In my humble opinion a first error could be that I don't see any column named "incident_history2.assigned_group".
I would try to use common table expression, to get only ticket number that contains "Desktop_support":
WITH desktop as (
SELECT distinct Ticket_Number
FROM incident_history
WHERE Assigned_Group = "Desktop Support"
),
Than an Inner Join of the result with your inner table to get ticket number and maxSeq, so in a second moment you can get also the "MAXGroup":
WITH tmp AS (
SELECT i2.Ticket_Number, i2.maxseq
FROM desktop D inner join
(SELECT Ticket_number, max(assigned_group_seq_no) as maxseq
FROM incident_history
GROUP BY ticket_number) as i2
ON D.Ticket_Number = i2.Ticket_Number
)
SELECT i.Ticket_Number, i.Assigned_Group as MAX_Group, T.maxseq, i.Reported_Date
FROM tmp T inner join incident_history i
ON T.Ticket_Number = i.Ticket_Number and i.assigned_group_seq_no = T.maxseq
I think there are several different method to resolve this question, but I really hope it's helpful for you!
For more information about Common Table Expression: https://www.essentialsql.com/introduction-common-table-expressions-ctes/

Calculate number of distinct instances of value in column

long time lurker. I've searched and searched though none of the solutions work for me.
I'm working in a Sybase (ASE) db (most mssql/mysql transactional db solutions will work just fine)
In my example, I'm trying to calculate/count the number of times a specific 'party_id' is listed in a column. The problem I'm having is that it's only counting FOR each row- so of course the count is always going to be 1.
See output:
(I would like for party_id 130568 to show '2' in the refs column, 125555 to show '5', etc.)
output
Here is my query:
select
count(distinct p.party_id) as refs,
p.party_id,
sp_first_party(casenum),
c.casenum,
mld.mailing_list,
p.our_client
from cases c
inner join party p on c.casenum=p.case_id
inner join names n on n.names_id=p.party_id
inner join mailing_list_defined mld on n.names_id=mld.names_id
where
mld.mailing_list like 'Mattar Stars'
and mld.addr_type like 'Home'
and n.deceased='N'
and p.our_client='Y'
group by p.party_id, c.casenum, mld.mailing_list, p.our_client
order by sp_first_party(casenum) asc
Any tips would be greatly appreciated.
Thank you
Sounds like you need to be using an APPLY statement. Not sure if the join criteria on the APPLY statement is correct, but you should be able to extrapolate the logic. See if that will work with Sybase.
SELECT pic.PartyInstanceCount AS refs
,p.party_id
,sp_first_party(casenum)
,c.casenum
,mld.mailing_list
,p.our_client
FROM cases AS c
INNER JOIN party AS p ON c.casenum = p.case_id
INNER JOIN names AS n ON n.names_id = p.party_id
INNER JOIN mailing_list_defined AS mld ON n.names_id = mld.names_id
OUTER APPLY (
SELECT COUNT(1) AS PartyInstanceCount
FROM party p2
WHERE p2.case_id = c.casenum
) pic
WHERE mld.mailing_list LIKE 'Mattar Stars'
AND mld.addr_type LIKE 'Home'
AND n.deceased = 'N'
AND p.our_client = 'Y'
ORDER BY
sp_first_party(casenum) ASC

Access data source using SQL to show most recent entry per site

First of all I am a complete beginner to SQL and have been thrown in at the deep end a bit ! I'm learning as I go along and each mistake I make or question I ask will hopefully help me develop... please be kind :)
I have a working query that extracts electricty meter readings and other information. I am after finding the most recent reading for each site. This is the query at the moment :
PARAMETERS [Site Group] Text ( 255 );
SELECT
Lookup.Lookup_Name AS [Group],
Contacts.Name AS Site,
Points.Number AS MPAN,
Max(DataElectricity.Date) AS MaxDate,
DataElectricity.M1_Present,
DataElectricity.M2_Present,
DataElectricity.M3_Present,
DataElectricity.M4_Present,
DataElectricity.M5_Present,
DataElectricity.M6_Present,
DataElectricity.M7_Present,
DataElectricity.M8_Present,
DataElectricity.Direct
FROM
DataElectricity INNER JOIN (Lookup INNER JOIN (Points INNER JOIN Contacts ON Points.Contacts_Id = Contacts.Id) ON Lookup.Lookup_Id = Contacts.Group_1) ON DataElectricity.Point_Id = Points.Id
WHERE
((DataElectricity.Direct)='D')
GROUP BY
Lookup.Lookup_Name, Contacts.Name, Points.Number, DataElectricity.M1_Present, DataElectricity.M2_Present, DataElectricity.M3_Present, DataElectricity.M4_Present, DataElectricity.M5_Present, DataElectricity.M6_Present, DataElectricity.M7_Present, DataElectricity.M8_Present, DataElectricity.Direct
ORDER BY
Lookup.Lookup_Name, Contacts.Name, Max(DataElectricity.Date) DESC;
However this returns all the readings for a site rather than just the most recent... I'm sure this is simple but I can't figure it out.
Any advice or guidence is gratefully received :)
Can't you just use top 1 to get only the first result?
SELECT top 1 ...
I have evolved the code a bit further using caspian's suggestion of SELECT top 1... but am struggling to refine it further and produce the result I need.
PARAMETERS [Site Group] Text ( 255 );
SELECT
Lookup.Lookup_Name,
Contacts.Name AS Site,
Points.Number AS MPAN,
DataElectricity.M1_Present,
DataElectricity.M2_Present,
DataElectricity.M3_Present,
DataElectricity.M4_Present,
DataElectricity.M5_Present,
DataElectricity.M6_Present,
DataElectricity.M7_Present,
DataElectricity.M8_Present,
DataElectricity.Direct
FROM
(
SELECT TOP 1 DataElectricity.Date AS MaxDate,
DataElectricity.M1_Present,
DataElectricity.M2_Present,
DataElectricity.M3_Present,
DataElectricity.M4_Present,
DataElectricity.M5_Present,
DataElectricity.M6_Present,
DataElectricity.M7_Present,
DataElectricity.M8_Present,
DataElectricity.Point_id
FROM
DataElectricity
ORDER BY MaxDate DESC
)
DataElectricity INNER JOIN (Lookup INNER JOIN (Points INNER JOIN Contacts ON Points.Contacts_Id = Contacts.Id) ON Lookup.Lookup_Id = Contacts.Group_1) ON DataElectricity.Point_Id = Points.Id
WHERE
((Lookup.Lookup_Name)=Lookup_Name)
ORDER BY
Lookup.Lookup_Name, Contacts.Name, MaxDate DESC;
I do have a Google Drive file showing a small example of the data tables and desired result with hopfully a clear guide as to how the tables connect.
https://docs.google.com/file/d/0BybrcUCD29TxWVRsV1VtTm1Bems/edit?usp=sharing
The actual data contains hundreds of Site Groups each with potentially hundreds of sites.
I would like my end users to be able to select the Site Group name from the Lookup.Lookup_Name list and for it to return all the relevant sites and readings.
.... I really hope that makes sense !

JOIN; only one record please!

OK, I have a complicated query from a poorly designed DB... In one query I need to get a count from one database, information from another with a link from another, here goes:
Each blog has a type (news, report etc) and a section Id for a certain part of the site but it also can be linked to multiple computer games and sections)
type ( blog_id, title, body, etc...) // yes I know the type is the name of the blog and not just an id number in the table not my design
blog_link ( blog_id, blog_type, section_id, game_id )
blog_comments (blog_id, blog_type, comment, etc...)
So the query goes a little like this:
SELECT bl.`blog_id`, count(bc.`blog_id`) AS 'comment_count', t.`added`
FROM blog_link bl
JOIN type t ON t.`id` = bl.`blog_id`
JOIN blog_comments bc ON (`item_id` = bl.`blog_id` AND `blog_type` = '[$type]')
WHERE bl.`section_id` = [$section_id] AND bl.`blog_type` = '[$type]'
GROUP BY bl.`blog_id`
ORDER BY `added` DESC
LIMIT 0,20
Now this is fine so long as I do not have multiple games associated with one blog.
Edit: So currently if more than one game is associated the comment_count is multiplied by the amount of games associated... not good.
I have no idea how I could do this... It just isn't working! If I could somehow group by the blog_id before I join it would be gold... anyone got an Idea?
Many thanks in advance
Dorjan
edit2: I've offered a bounty as this problem surely can be solved!! Come on guys!
It seems like you just want to get a DISTINCT count, so just add DISTINCT inside the count. Although you will need to add some sort of unique identifier for each comment. Ideally you would have a unique id (ie. auto increment) for each comment, but if you don't you could probably use blog_id+author+timestamp.
SELECT bl.`blog_id`, count(DISTINCT CONCANT(bc.`blog_id`,bc.`author`,bc.`timestamp`) AS 'comment_count',...
That should give you a unique comment count.
I think you need to get the blogs of type "X" first, then do a count of comments for those blogs.
SELECT
EXPR1.blog_id,
count(bc.`blog_id`) AS 'comment_count'
FROM
(
SELECT
bl.blog_id, t.added
FROM
blog_link bl
JOIN
type t ON t.id = bl.blog_id
WHERE
bl.`section_id` = [$section_id]
AND
bl.`blog_type` = '[$type]'
GROUP BY
bl.`blog_id`
ORDER BY
`added` DESC
LIMIT 0,20
) AS EXPR1
JOIN
blog_comments bc ON
(
bc.item_id = EXPR1.blog_id
)
Not tested :
SELECT bl.`blog_id`, count(bc.`blog_id`) AS 'comment_count', t.`added`
FROM
(
SELECT DISTINCT blog_id, blog_type
FROM blog_link
WHERE
`section_id` = [$section_id]
AND `blog_type` = '[$type]'
) bl
INNER JOIN blog_comments bc ON (
bc.`item_id` = bl.`blog_id` AND bc.`blog_type` = bl.`blog_type`
)
INNER JOIN type t ON t.`id` = bl.`blog_id`
GROUP BY bl.`blog_id`
ORDER BY t.`added` DESC
LIMIT 0,20