Access Append Query compare with table - sql

I am currently rebuilding a messy Access Database and I entcountered the following problem:
I've got a Table of facilities which contain a row called district. Those Rows contain a number linked to another table which just contains the numbers and names of districts. I added a lookup Column with the Name of the district displayed.
I now want to change the new column for every row depending on the data in the old row.
Facilities
NAME|..|DISTRICT_OLD
A |..| 1
B |..| 2
C |..| 1
...
DISTRICTS
ID|NAME
1 |EAST
2 |WEST
...
I would like something like the following:
Facilities
NAME|..|DISTRICT_OLD|DISTRICT
A |..| 1|EAST
B |..| 2|WEST
C |..| 1|EAST
...
The District Field (lookup) gets its Data like follows SELECT [DISTRICTS].ID, [DISTRICTS].NAME FROM DISTRICTS ORDER BY [NAME];
(Thanks to Gordon Linoff) I could get the query but I do now struggle with the insert. I can get the Data I want:
SELECT [DISTRICTS].NAME FROM Facilities INNER JOIN DISTRICTS ON Facilities.DISTRICT_OLD = [DISTRICTS].ID;
If I try to INSERT INTO Facilities(DISTRICT) It says Typerror.
How can I modify the data to be compatible with a lookup column?
I guess I need to select the ID as well which isnt't a problem but then the error says to many columns.
I hope I haven't mistaken any names, my Access isn't running the english language.
Can you help me?
Fabian

Lookup columns are number (long integer)
with a relational database, you only need the single column containing the ID (as you always lookup the district.name with a query) so:
INSERT INTO Facilities(DISTRICT) SELECT 4
where 4 is the ID of the record in the lookup table that you want, or better still:
INSERT INTO Facilities(DISTRICT)
SELECT ID FROM DISTRICTS
where District.Name = "Name you want the ID for"

Related

Dividing one column into two, then joining new columns with other tables

I have a DB with three tables.
"Campaign" table has a column "Campaign number" (e.g. value = 1)
"Payment" table has a column "user_id" (e.g. value = 134356)
"User_Source" table has a column "dump" which contains both the user id and campaign number: info_u134356_cpn_1 OR info_cpn_1_u134356
I need to divide the data from the combined values in user_source, so that I would be able to see user_id and their linked campaign number in one table, and then count how many users are attributed to each campaign.
I can't get my head around the way to split ths column, and whether there is a way to do s without spitting (e.g. somehow filtering).
I'm currently using DataGrip for this.
You can use regexp_match() in Postgres:
with sample (dump) as (
values
('info_cpn_1_u134356'),
('info_u456789_cpn_5')
)
select (regexp_match(dump, 'u([0-9]+)'))[1] as user_id,
(regexp_match(dump, 'cpn_([0-9]+)'))[1] as campaign
from sample;
returns:
user_id | campaign
--------+---------
134356 | 1
456789 | 5

How do I make a query for if value exists in row add a value to another field?

I have a database on access and I want to add a value to a column at the end of each row based on which hospital they are in. This is a separate value. For example - the hospital called "St. James Hospital" has the id of "3" in a separate field. How do I do this using a query rather than manually going through a whole database?
example here
Not the best solution, but you can do something like this:
create table new_table as
select id, case when hospital="St. James Hospital" then 3 else null
from old_table
Or, the better option would be to create a table with the columns hospital_name and hospital_id. You can then create a foreign key relationship that will create the mapping for you, and enforce data integrity. A join across the two tables will produce what you want.
Read about this here:
http://net.tutsplus.com/tutorials/databases/sql-for-beginners-part-3-database-relationships/
The answer to your question is a JOIN+UPDATE. I am fairly sure if you looked up you would find the below link.
Access DB update one table with value from another
You could do this:
update yourTable
set yourFinalColumnWhateverItsNameIs = {your desired value}
where someColumn = 3
Every row in the table that has a 3 in the someColumn column will then have that final column set to your desired value.
If this isn't what you want, please make your question clearer. Are you trying to put the name of the hospital into this table? If so, that is not a good idea and there are better ways to accomplish that.
Furthermore, if every row with a certain value (3) gets this value, you could simply add it to the other (i.e. Hospitals) table. No need to repeat it everywhere in the table that points back to the Hospitals table.
P.S. Here's an example of what I meant:
Let's say you have two tables
HOSPITALS
id
name
city
state
BIRTHS
id
hospitalid
babysname
gender
mothersname
fathername
You could get a baby's city of birth without having to include the City column in the Births table, simply by joining the tables on hospitals.id = births.hospitalid.
After examining your ACCDB file, I suggest you consider setting up the tables differently.
Table Health_Professionals:
ID First Name Second Name Position hospital_id
1 John Doe PI 2
2 Joe Smith Co-PI 1
3 Sarah Johnson Nurse 3
Table Hospitals:
hospital_id Hospital
1 Beaumont
2 St James
3 Letterkenny Hosptial
A key point is to avoid storing both the hospital ID and name in the Health_Professionals table. Store only the ID. When you need to see the name, use the hospital ID to join with the Hospitals table and get the name from there.
A useful side effect of this design is that if anyone ever misspells a hospital name, eg "Hosptial", you need correct that error in only one place. Same holds true whenever a hospital is intentionally renamed.
Based on those tables, the query below returns this result set.
ID Second Name First Name Position hospital_id Hospital
1 Doe John PI 2 St James
3 Johnson Sarah Nurse 3 Letterkenny Hosptial
2 Smith Joe Co-PI 1 Beaumont
SELECT
hp.ID,
hp.[Second Name],
hp.[First Name],
hp.Position,
hp.hospital_id,
h.Hospital
FROM
Health_Professionals AS hp
INNER JOIN Hospitals AS h
ON hp.hospital_id = h.hospital_id
ORDER BY
hp.[Second Name],
hp.[First Name];

Normalise/join SQL Server tables

I have inherited a SQL server database which isn't normalised and is giving me headaches. I am not very experienced in SQL and maybe asking stupid questions but would appreciate any advice on how to go forward with the below scenarios.
I have three tables as follows:-
A table of results:
**ResId CompId Name Result**
1 1 Band A 2
2 1 Band B 1
3 1 Band C 3
4 2 Band A* 2
5 2 Band B 1
6 2 Band C 3
A table of Bands current names:
**BandId BandName**
1 Band A
2 Band B
3 Band C
A table of names the bands were previously known as (linked on BandId):
**oldBandId BandId oldBandName**
1 1 Band A*
2 1 Band a
2 2 Band b
I am looking to consolidate the list of band names in the results table, replacing the band name with a bandId however the result table contains band names from both tables. First question should I create some sort of join table and use this as the bandId in the results table? If so What do I need in this join table, is it just a psuedo-Id of bandId/oldBandId and the table name concatenated then this placed in the results table?
I am then looking to use a query to select all results where the user selects the band by any name variant (new or old) and returns the results including all names linked with the band i.e. choosing Band A would return the results for both Band A and Band A*.
Thanks in advance
Steve
I like the idea of using the band id in the results table. I would suggest eliminating the "old band name" table and replace it with a table of band aliases, since that sounds more like what you want. The band alias table would just have the band id and an one alias per row.
I think your current db structure is fine enough - I can't think of any way to improve on it, without complicating it further (especially if you want to retain the old band names).
You can just write a query as so for your need -
select * from results
where Name = #bandName or
Name in (select oldBandName
from oldBands
where BandId in (select BandId
from Bands
where BandName = #bandName))

Fetch a single field from DB table into itab

I want to fetch the a field say excep_point from a transparent table z_accounts for the combination of company_code and account_number. How can I do this in ABAP SQL?
Assume that table structure is
|company_code | account_number | excep_point |
Assuming you have the full primary key...
data: gv_excep_point type zaccounts-excep_point.
select single excep_point
into gv_excep_point
from zaccounts
where company_code = some_company_code
and account_number = some_account_number.
if you don't have the full PK and there could be multiple values for excep_point
data: gt_excep_points type table of zaccounts-excep_point.
select excep_point
into table gt_excep_points
from zaccounts
where company_code = some_company_code
and account_number = some_account_number.
There is at least another variation, but those are 2 I use most often.
For information only. When you selects data into table you can write complex expressions to combine different fields. For example, you have internal table (itab) with two fields "A" and "B". And you are going to select data from DB table (dbtab) wich have 6 columns - "z","x","y","u","v","w". And for example each field is type char2 You aim to cimbine "z","x","y","u" in "A" field of internal table and "v","w" in "B" field. You can write simple code:
select z as A+0(2)
x as A+2(2)
y as A+4(2)
u as A+6(2)
v as B+0(2)
w as B+2(2) FROM dbtab
INTO CORRESPONDING FIELDS OF TABLE itab
WHERE <where condition>.
This simple code makes you job done very simple
In addition to Bryans answer, here is the official online documentation about Open SQL.

I DISTINCTly hate MySQL (help building a query)

This is staight forward I believe:
I have a table with 30,000 rows. When I SELECT DISTINCT 'location' FROM myTable it returns 21,000 rows, about what I'd expect, but it only returns that one column.
What I want is to move those to a new table, but the whole row for each match.
My best guess is something like SELECT * from (SELECT DISTINCT 'location' FROM myTable) or something like that, but it says I have a vague syntax error.
Is there a good way to grab the rest of each DISTINCT row and move it to a new table all in one go?
SELECT * FROM myTable GROUP BY `location`
or if you want to move to another table
CREATE TABLE foo AS SELECT * FROM myTable GROUP BY `location`
Distinct means for the entire row returned. So you can simply use
SELECT DISTINCT * FROM myTable GROUP BY 'location'
Using Distinct on a single column doesn't make a lot of sense. Let's say I have the following simple set
-id- -location-
1 store
2 store
3 home
if there were some sort of query that returned all columns, but just distinct on location, which row would be returned? 1 or 2? Should it just pick one at random? Because of this, DISTINCT works for all columns in the result set returned.
Well, first you need to decide what you really want returned.
The problem is that, presumably, for some of the location values in your table there are different values in the other columns even when the location value is the same:
Location OtherCol StillOtherCol
Place1 1 Fred
Place1 89 Fred
Place1 1 Joe
In that case, which of the three rows do you want to select? When you talk about a DISTINCT Location, you're condensing those three rows of different data into a single row, there's no meaning to moving the original rows from the original table into a new table since those original rows no longer exist in your DISTINCT result set. (If all the other columns are always the same for a given Location, your problem is easier: Just SELECT DISTINCT * FROM YourTable).
If you don't care which values come from the other columns you can use a (bad, IMHO) MySQL extension to SQL and do:
SELECT * FROM YourTable GROUP BY Location
which will give a result set with one row per location and values for the other columns derived from the original data in an undefined fashion.
Multiple rows with identical values in all columns don't have any sense. OK - the question might be a way to correct exactly that situation.
Considering this table, with id being the PK:
kram=# select * from foba;
id | no | name
----+----+---------------
2 | 1 | a
3 | 1 | b
4 | 2 | c
5 | 2 | a,b,c,d,e,f,g
you may extract a sample for every single no (:=location) by grouping over that column, and selecting the row with minimum PK (for example):
SELECT * FROM foba WHERE id IN (SELECT min (id) FROM foba GROUP BY no);
id | no | name
----+----+------
2 | 1 | a
4 | 2 | c