Select Last movement for each ID in Access - sql

I am working on a MS-Access table, and would like to have a query to result all the information on the last entry from a certain id.
My table (DEPOSIT_MOVEMENTS) is the following:
MOV_CODE | WORK | DEPOSIT_CODE | TYPE | DATE | DESTINATION
I am looking to obtain for each DEPOSIT_CODE the latest register (on date), and obtain the *MOV_CODE so that I can get the DESTINATION of the item.
DEPOSIT_CODE may have many MOV_CODE on different dates.
I have tried with different options posted on stackoveflow, but I coudl not get any of these to work properly.
Right now I am trying with the GROUP BY, but cannot get it working.
SELECT t1.[DEPOSIT_CODE], MAX(t1.[DATE]), t1.[MOV_CODE]
FROM [DEPOSIT_MOVEMENTS] AS t1
GROUP BY t1.[DEPOSIT_CODE];
Any help or guidance is welcome.
Kind regards,

Here is one method:
SELECT dm.*
FROM [DEPOSIT_MOVEMENTS] AS dm
WHERE dm.DATE = (SELECT MAX(dm2.DATE)
FROM [DEPOSIT_MOVEMENTS] AS dm2
WHERE dm2.DEPOSIT_CODE = dm.DEPOSIT_CODE
);

Related

Microsoft SQL Server generates two select queries and puts data in separate columns

I am looking for a query that separate the data with the condition WHERE in the same output but in separates columns.
Example: I have the table Product_2:
I have two separates queries (to separate the products by Produt_Tag):
SELECT
Product_Mark AS "PIT-10_Product_Mark",
Product_Model AS "PIT-10_Product_Model"
FROM Product_2
WHERE Product_Tag = 'PIT-10';
SELECT
Product_Mark AS "PIT-11_Product_Mark",
Product_Model AS "PIT-11_Product_Model"
FROM Product_2
WHERE Product_Tag = 'PIT-11';
And I get this output:
But I need the output to be like this:
Can someone tell me how I need to modify my query to have the four columns in the same table/ output?
Thank you
I forgot to tell that in the data I Have the “Porduct_Mark” that only appears one time. (in reality the data in “Product_Mark” is the name of the place where the instrument is located and one place can have one or two instruments “Product_Model”. At the end I’m looking for the result show in the image here below. I tried to use LEFT JOIN but that don’t work.
here is the new table "Product_2"
Result that I'm looking for:
Luis Ardila
I am assuming Product_PK is the primary key for the table and the repeated value 1002 shown in the question is a mistake. Considering this assumption, you can get the result set using self join as below.
SELECT pa.Product_Mark AS "PIT-10_Product_Mark", pa.Product_Model AS "PIT-10_Product_Model",
pb.Product_Mark AS "PIT-11_Product_Mark", pb.Product_Model AS "PIT-11_Product_Model"
FROM Product_2 pa
INNER JOIN Product_2 pb
ON pa.Product_Mark = pb.Product_Mark
WHERE pa.product_pk != pb.product_pk
and pa.Product_Tag = 'PIT-10'
and pb.Product_Tag = 'PIT-11';
verified same in https://dbfiddle.uk/NiOO8zc1

SQL One to many relationships, duplicate/results being returned as unique rows

I have a database and some of the tables have one to many relationships. How do I eliminate the results being returned as its own unique row?
For instance I have a initiative table and a initiative can have many funding requirements. When I perform an inner join I'm getting the results but it looks like the rows are duplicating to output a unique value from the funding table.
From the results, it should be like this
Row 3,4,5 should be in one row listing the results with the the funding required
Description | Acad_priority_1 | Acad_priority_2 | beginning_fiscal_year |
Develop... | false | true | 2018/2019 |
| 2018/2019 |
| 2019/2020
Can you please steer me in the right direction or show me how the SQL should be structured to achieve this?
SQL:
SELECT plan_master.plan_id,
plan_master.date_submitted,
plan_master.filename,
initiative_master.plan_id,
initiative_master.NAME,
initiative_master.acad_priority_1,
funding.initiative_id,
funding.beginning_fiscal_year
FROM plan_master
JOIN initiative_master
ON plan_master.plan_id = initiative_master.plan_id
JOIN funding
ON initiative_master.initiative_id = funding.initiative_id
ORDER BY Filename
|plan_id|date_submitted|filename|plan_id|NAME|acad_priority_1|initiative_id|begginning_fiscal_year|
|16F44FFE-5434-4E52-9D9A-F45C0A49D8E2|2018-12-03|1.txt|16F44FFE-5434-4E52-9D9A-F45C0A49D8E2|Space Utilization framework|false|8CCE0311-0E3C-467D-B675-04817A473056|2018/2019
|16F44FFE-5434-4E52-9D9A-F45C0A49D8E2|2018-12-03|1.txt|16F44FFE-5434-4E52-9D9A-F45C0A49D8E2|Space Utilization framework|false|8CCE0311-0E3C-467D-B675-04817A473056|2019/2020
|16F44FFE-5434-4E52-9D9A-F45C0A49D8E2|2018-12-03|1.txt|16F44FFE-5434-4E52-9D9A-F45C0A49D8E2|Space Utilization framework|false|8CCE0311-0E3C-467D-B675-04817A473056|2020/2021
The 2 beginning fiscal year values cannot be combined into a single row unless you want to concatenate them with commas (or another separator), or write a function to show the value as a range, for example 2018-2020. You can however get rid of the 4th record using distinct or using the below mentioned over/partition by clauses.
If you don't mind, can you run the following query and provide the results that will help me identify the duplication issue:
SELECT plan_master.plan_id,
plan_master.date_submitted,
plan_master.filename,
plan_master.department,
plan_master.last_name,
plan_master.first_name,
plan_master.email,
plan_master.mission_statement,
plan_master.vision_statement,
plan_master.goals_objectives,
initiative_master.plan_id,
initiative_master.NAME,
initiative_master.description,
initiative_master.acad_priority_1,
initiative_master.acad_priority_2,
initiative_master.acad_priority_3,
initiative_master.acad_priority_4,
initiative_master.acad_priority_5,
initiative_master.acad_priority_6,
initiative_master.operational_sustainability,
initiative_master.people_plan,
funding.initiative_id,
funding.beginning_fiscal_year
FROM plan_master
JOIN initiative_master
ON plan_master.plan_id = initiative_master.plan_id
JOIN funding
ON initiative_master.initiative_id = funding.initiative_id
ORDER BY Filename
Once you get to the cause, you can either use a better join clause (multiple conditions), add a where clause, or use the OVER clause in conjunction with the PARTITION BY clause to filter the data based on a ROW_NUMBER().
A simple join returns a cartesion product. If one table has 2 rows and another has 3, then there will be 6 rows of data. Need to do distinct on the data. You can do this:
SELECT plan.date_submitted,
plan.filename,
plan.department,
plan.last_name,
plan.first_name,
plan.email,
plan.mission_statement,
plan.vision_statement,
plan.goals_objectives,
initiative.Name,
initiative.description,
initiative.acad_priority_1,
initiative.acad_priority_2,
initiative.acad_priority_3,
initiative.acad_priority_4,
initiative.acad_priority_5,
initiative.acad_priority_6
FROM plan_master as plan
inner join (select distinct init.plan_id, init.NAME,
init.description,
init.acad_priority_1,
init.acad_priority_2,
init.acad_priority_3,
init.acad_priority_4,
init.acad_priority_5,
init.acad_priority_6,
init.operational_sustainability,
init.people_plan,
funding.beginning_fiscal_year from initiative_master as init
join funding on funding.initiative_id = init.initiative_id ) as initiative
ON plan.plan_id = initiative.plan_id
ORDER BY Filename

How to Group_Concat with a 3-table JOIN for genealogy

I am failing to grasp how I can get the following outcome. I thought perhaps via GROUP_CONCAT, but I am also joining on 3 tables, and unclear on the correct syntax or if this is even the best approach.
Generic table layout:
Table Users: user_id | first | last
Table Orgs org_id | org_name
Table Relationship user_id | org_id | start_year | end_year
The relationship table has MANY entries, that may be associated with that specific user_id.
I need to get the User columns: id, first, last. I'd like to try and group the org data into 1 concatenated, delimited field. Maybe a double group_concatenation is needed? Which would consist of the org_id, org_name, start_year & end_year for all records in the relationship table that match the user_id. I'm hoping for an output like this:
Each '|' represents a new column/piece of data.
If there was only 1 org_id associated with the user_id, the output would be (similar) to:
user_id | first | last | org_id-org_name-start_year-end_year
If there were more than 1 org found/associated with that user_id, the output would have more concatenated/delimited data in the same column:
user_id | first | last | org_id-org_name-start_year-end_year^org_id-org_name-start_year-end_year^org_id-org_name-start_year-end_year
(Notice the '-' delimiter between values and the '^' delimiter between new 'org-grouped' data.)
When I grab that data, I can then just break it up (on the backend/PHP side of things) into an array or whatever.
I'm not sure how I can GROUP_CONCAT (if that is even the best approach here?) while I have to JOIN on 3 separate tables.
This is not my REAL query. (I'm not sure if I should post it, as I do not want to cause any confusion as it does NOT match my dummy table/column names.)
I just wanted to show my attempt that gets me 3 individual rows, (using my JOINS) but no GROUP_CONCAT stuff:
SELECT genealogy_users.imis_id, genealogy_users.full_name,
genealogy_users.member_email, genealogy_orgs.org_id,
genealogy_orgs.org_name, genealogy_relations.user_id,
genealogy_relations.relation_type, genealogy_relations.start_year,
genealogy_relations.end_year
FROM genealogy_users
INNER JOIN genealogy_relations ON genealogy_users.imis_id = genealogy_relations.user_id
INNER JOIN genealogy_orgs ON genealogy_relations.org_id = genealogy_orgs.org_id
WHERE genealogy_users.imis_id = '00003';
UPDATE:
Well I seemed to have fudged my way through it. But I'm not sure how legit this is.
Its -ALMOST- there. I believe I still need a JOIN or something? Since the genealogy_orgs.org_id = '84864' is hardcoded, and it should NOT be. Maybe it needs to come from a JOIN or something?
SELECT genealogy_users.*,
(SELECT GROUP_CONCAT(org_id,'-',
(SELECT org_name FROM genealogy_orgs WHERE genealogy_orgs.org_id = '84864'),
'-',start_year,'-',end_year,'^')
FROM genealogy_relations WHERE genealogy_relations.user_id = genealogy_users.imis_id
) AS alumni_list
FROM genealogy_users
WHERE genealogy_users.imis_id = '00003';
UPDATE 2:
My final attempt, which I think is getting me what I need. (But it's late, and I'll check back tomorrow and look at things more closely.)
SELECT genealogy_users.imis_id, genealogy_users.full_name,
genealogy_users.member_email, genealogy_orgs.org_id,
genealogy_orgs.org_name, genealogy_relations.user_id,
genealogy_relations.relation_type, genealogy_relations.start_year,
genealogy_relations.end_year,
(SELECT GROUP_CONCAT(org_id,'-',org_name,'-',start_year,'-',end_year,'^')
FROM genealogy_relations
WHERE genealogy_relations.user_id = genealogy_users.imis_id
) AS alumni_list
FROM genealogy_users
INNER JOIN genealogy_relations ON genealogy_users.imis_id = genealogy_relations.user_id
INNER JOIN genealogy_orgs ON genealogy_relations.org_id = genealogy_orgs.org_id
WHERE genealogy_users.imis_id = '00003';
Is there anything to make note of in the above attempt? Or is there a better approach? Hopefully something easily readable so it makes sense?

SQL - Getting a column from another table to join this query

I've got the code below which displays the location_id and total number of antisocial crimes but I would like to get the location_name from a different table called location_dim be output as well. I tried to find a way to UNION it but couldn't get it to work. Any ideas?
SELECT fk5_location_id , COUNT(fk3_crime_id) as TOTAL_ANTISOCIAL_CRIMES
from CRIME_FACT
WHERE fk1_time_id = 3 AND fk3_crime_id = 1
GROUP BY fk5_location_id;
You want to use join to lookup the location name. The query would probably look like this:
SELECT ld.location_name, COUNT(cf.fk3_crime_id) as TOTAL_ANTISOCIAL_CRIMES
from CRIME_FACT cf join
LOCATION_DIM ld
on cf.fk5_location_id = ld.location_id
WHERE cf.fk1_time_id = 3 AND cf.fk3_crime_id = 1
GROUP BY ld.location_name;
You need to put in the right column names for ld.location_name and ld.location_id.
you need to find a relationship between the two tables to link a location to crime. that way you could use a "join" and select the fields from each table you are interested in.
I suggest taking a step back and reading up on the fundamentals of relational databases. There are many good books out there which is the perfect place to start.

Need to pull only last date in table that stores change dates SQL / ODBC

Hope somebody can help me with this. I'm trying to pull a list of forthcoming titles (I work in publishing) via ODBC/ms query. I want (amongst other things) to show their internal status (approved, prepress etc.). The database stores the change dates for the status'. I seem to be getting one line per status per title. So if the title has changed status 6 times, I will get 6 lines. But I only want to show the latest status...
The date is in BL_PROJECT_TO_STATUS.STATUS_DATE (I've inserted a date criteria beneath, just to make it more visible).
How can this be done? I'm very new to ODBC and would appreciate it a lot.
SELECT DISTINCT
BL_PROJECT.EXP_PUB_DATE, BL_PROJECT.EAN, BL_PROJECT.TITEL,
MEDIATYPE.DESCRIPTION, BL_PROJECT_STATUS.DESCRIPTION
FROM
FIRMA1.BL_PROJECT BL_PROJECT, FIRMA1.BL_PROJECT_STATUS BL_PROJECT_STATUS,
FIRMA1.BL_PROJECT_TO_STATUS BL_PROJECT_TO_STATUS, FIRMA1.MEDIATYPE MEDIATYPE
WHERE
BL_PROJECT.PROJECT_ID = BL_PROJECT_TO_STATUS.PROJECT_ID AND
BL_PROJECT_TO_STATUS.STATUS_ID = BL_PROJECT_STATUS.CODE AND
BL_PROJECT.MEDIATYPE = MEDIATYPE.ID AND
((BL_PROJECT.PROJECT_TYPE = 2) AND
(BL_PROJECT.EXP_PUB_DATE Between SYSDATE AND (SYSDATE+90)) AND
(BL_PROJECT_TO_STATUS.STATUS_DATE = {ts '2013-11-20 00:00:00'}))
ORDER BY
BL_PROJECT.EXP_PUB_DATE, BL_PROJECT.EAN, BL_PROJECT.TITEL
Here is the general idea. You can adapt it with your table and field names.
select somefields
from sometables
join
(select something, max(datetimefield) maxdt
from table1
where whatever
group by something ) temp on table1.datetimefield = maxdt
etc