Oracle SQL - need to flip values, but don't know how - sql

select kasutaja_nimi, eesnimi, perenimi, r_nimetus, seeria_nr, max(paigalduse_aeg) as paigaldus
from kasutaja ka
right join riistvara ri on ka.id = ri.id
right join r_paigaldus r on ka.id = r.kasutaja_id
group by kasutaja_nimi, eesnimi, perenimi, seeria_nr, r_nimetus;
This is the output, but I need those values changed. I have ID primary keys for both - kasutaja and riistvara, but I don't know how to match kasutaja ID 1 with riistvara ID 2 and vice versa.
And the output should be like this:
The R_NIMETUS and SEERIA_NR fields are different on my output what I get with my code.

you can't cross the data because you haven't a logic link between two tables.
You have only one solution, you must change your table structure:
Scenario 1
If you have a parent - child relation, please add a foreign key on child table
Scanerio 2
If you have a n:m relationship, please create a middle table with fks to parent and child table.
So in your query you can use JOIN operations to show correctly your results

Related

Join Table vs Foreign Key/Ref

Imagine I have two tables and they have a 1-to-Many relationship. Is it better to have a Join table storing the relationship, or issuing a foreign key in one of these tables? Take a look of these two situations:
Situation A:
Table 1: CreditCard
Table 2: Person
It seems to me quite making sense to put the creditCard_id as part of the Person table
Situation B:
Table 1: Order
Table 2: Person
This time I think I will put the order_id and person_id in a Join table?
Am I making a mistake in the above? Is there a standard/better way of determining this?
For 1 to Many relation, people usually put the foreign key into the heavier table or the "Many" table.
So from your example, both go CreditCard and Order tables, by doing so you will remove duplicate data.
Imagine you which one is better:
FK goes to the "Many" table
Table People:
ID NAME
1 A
2 B
Table CreditCard:
ID PEOPLE_ID
1 1
2 1
FK goes to "1" table:
Table People:
ID NAME CreditCard_ID
1 A 1
1 A 2
2 B 3
Table CreditCard:
ID
1
2
3
Note: See how the ID and Name are repeated(ID=1, NAME=A) in the second example, that happens if you put the FK in the wrong table.
I would make three tables; a person table with all their info( name, address, etc. ), a credit card table with all the info( expiration date, security number?, etc.. ) then another table connecting them with the PersonID and CreditCardID. But what do I know, I'm still in school lol so wait for someone else to answer you.

SQL Server : show foreign key constraints tied to a single record

This probably is a bit complicated but is there anyway or already a script out there that could show you all foreign key constraints tied to a single table row.
What I mean by this is say you have the following DB structure:
TABLE 1
column a
column b
TABLE 2
column c
column d (foreign key constraint to 1.a)
TABLE 3
column e
column f (foreign key constraint to 2.c)
TABLE 4
column g (foreign key constraint to 3.e)
column h
Then, you have 2 rows in Table 1. One of the rows is constrained through table 2, then further to table 3, BUT not further to table 4 (IDs tied throughout tables 1-3).
I would like to simply query one of the rows in Table 1 and have it tell me that for that row there are ties that go to Table 2, and then those rows have ties to Table 3. Using this 'query' on the second row in Table 1 would simply just return nothing as there are no foreign keys that are tying that row down.
Something like this would be immensely useful when it comes to tracking down what tables/rows are currently using a particular starting row.
Thanks!
I think what you're looking for can be accomplished by:
SELECT a, t2=COUNT(d), t3 = COUNT(f), t4 = COUNT(g)
FROM [1] LEFT JOIN [2] ON 1.a=2.d
LEFT JOIN [3] ON 2.c = 3.f
LEFT JOIN [4] ON 4.g = 3.e

In SQL How do I copy values from one table to another based on another field's value?

Okay I have two tables
VOUCHERT with the following fields
ACTIVATIONCODE
SERIALNUMBER
VOUCHERDATADBID
UNAVAILABLEAT
UNAVAILABLEOPERATORDBID
AVAILABLEAT
AVAILABLEOPERATORDBID
ACTIVATIONCODENEW
EXT1
EXT2
EXT3
DENOMINATION -- I added this column into the table.
and the second table is VOUCHERDATAT with the following fields
VOUCHERDATADBID
BATCHID
VALUE
CURRENCY
VOUCHERGROUP
EXPIRYDATE
AGENT
EXT1
EXT2
EXT3
What I want to do is copy the corresponding VALUE from VOUCHERDATAT and put it into DENOMINATION of VOUCHERT. The linking between the two is VOUCHERDATADBID. How do I go about it?
It is not a 1:1 mapping. What I mean is there may be 1000 SERIALNUMBERS with a same VOUCHERDATADBID. And that VOUCHERDATADBID has only entry in VOUCHERDATAT, hence one value. Therefore, all serial numbers belonging to a certain VOUCHERDATADBID will have the same value.
Will JOINS work? What type of JOIN should I use? Or is UPDATE table the way to go?
Thanks for the help !!
Your problem is one of design. None of your tables are in any of the normal forms, not even in the first normal form (1NF). You should not add a column to the VOUCHERT table, but create a new table (pick the name) with the following columns: SERIALNUMBER, VALUE, VOUCHERDATADBID (maybe ACTIVATIONCODE too - need to know the primary key on VOUCHERT to be sure if ACTIVATIONCODE should be included in the new table). Normalization is the database design process that aims to resolve any possible INSERT/UPDATE/DELETE anomalies. This should solve your INSERT issue.
Hope this helps.
You can do a join between these two tables and you will get a 'view'. You can update this view like:
UPDATE (SELECT *
FROM VOUCHERT A JOIN VOUCHERDATAT B
ON A.VOUCHERDATADBID = B.VOUCHERDATADBID)
SET DENOMINATION = VALUE;
You may put outer join if you need.
VOUCHERDATADBID MUST BE PRIMARY KEY in VOUCHERDATAT and FOREIGN KEY in VOUCHERT, otherwise you will get an error:
ORA-01779: cannot modify a column which maps to a non key-preserved table
update (
select v.DENOMINATION
, vd.VALUE
from VOUCHERT v
join VOUCHERDATAT vd
on vd.VOUCHERDATADBID = v.VOUCHERDATADBID
) t
set t.DENOMINATION = t.Value
If the voucherdatadbid is not a primary key, this should work:
UPDATE vouchert
SET denomination =
(SELECT MAX(value)
FROM voucherdatat
WHERE voucherdatadbid = vouchert.voucherdatadbid);

How can I SELECT DISTINCT on one (excluded) column, but include other columns in the query? (ORACLE)

So I have data arranged loosely like this:
Table 1 - PEOPLE: person_id (primary key), parent_id, child_id, other_parent_fields, other_child_fields
Table 2 - PARENTS: parent_id (auto incrementing primary key), other_fields
Table 3 - CHILDREN: child_id (auto incrementing primary key), parent_id(foreign key referencing PARENTS) other_fields
I want to be able to query for all of the distinct parents from the PEOPLE table, and insert all of the other_parent_fields into the PARENTS table, throwing out the old parent_id from Table 1, in favor of my auto incrementing parent_id in table 2.
I also want to do the same for children, but maintain the parent-child relationships, only using my own ids from table 2 and table 3.
Essentially, I am trying to change the way that the database is designed. Rather than a whole table for all people, I am creating a PARENTS table and a CHILDREN table, the latter of which refers to PARENTS with a foreign key. The reason I am throwing out the ids from table 1 is because I have no reason to care about them in my new table (i.e. the numbering can start back from one, and additional entries can just auto increment the primary key). However, before discarding these IDs from table 1, I need to capture the parent-child relations that they relay.
Is this even possible? How would one go about doing it?
we can assume, for simplicity that no children have children i.e. someone cant be a parent and a child
I did not fully understand your question but it seems that you first query would be this (SQL Server syntax):
insert into Parents
select other_parent_fields, person_id as legacy_parent_id
from (select distinct person_id, other_parent_fields from PEOPLE where parent_id is null) x
The trick would be to first group on parent_id, other_parent_fields and then discard the parent_id. (A distinct is equal to a group by *). The above query only works if other_parent_fields is a pure function of parent_id. I interpret your question as an attempt to normalize denormalized data, so I guess this is true.
In order to extract the children you can do this:
insert into Children
select other_child_fields, parent_id as legacy_parent_id
from (select distinct person_id, other_child_fields from PEOPLE where parent_id is not null) x
Now your tables contain the distinct parents and children as well as their old IDs. You have to write an update query now that assigns the new parent ids into the children table. Then you drop the legacy fields.

Finding the depth of a set of related tables for a given Primary Key

I am trying to figure out a stored procedure that can get a the depth of a table structure. Bear in mind the table design was before my time and cannot be altered.
When I say depth (to ellaborate), I mean the highest section table that has a record originating from a JobID.
I am really rusty with my SQL so I am brain farting a clever way to to return the depth of a given jobID record.
Any help is appreciated!
Section1
|JobID -- FK
|SectID -- PK
Section2
|Sect1ID -- FK
|Sect2ID -- PK
Section3
|Sect2ID -- FK
|Sect3ID -- PK
Section4
|Sect3ID -- FK
|Sect4ID -- PK
If the schema is fully known to you (as above), then you could simply do (for a single JobID). Note that I have augmented each table to facilitate the COALESCE.
SELECT COALESCE(Section4.SecName
,Section3.SecName
,Section2.SecName
,Section1.SecName) AS DeepestSection
FROM (SELECT 'Section1' AS SecName, * FROM Section1) AS Section1
LEFT JOIN (SELECT 'Section2' AS SecName, * FROM Section2) AS Section2
ON Section2.Sect1ID = Section1.SectID
LEFT JOIN (SELECT 'Section3' AS SecName, * FROM Section3) AS Section3
ON Section3.Sect2ID = Section2.Sect2ID
LEFT JOIN (SELECT 'Section4' AS SecName, * FROM Section4) AS Section4
ON Section4.Sect3ID = Section3.Sec3tID
WHERE Section1.JobID = whatever
If would be changed up slightly to do an analysis over all jobs.
If the number of tables with references trickling back up to JobID is not yet fully known to you at this time, you would use the Information Schema views http://msdn.microsoft.com/en-us/library/ms186778.aspx - use this to traverse the defined constraints and determine dependencies - creating necessary SQL to do the above along the way in dynamic form and then executing it.