Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I have a request for an attribute in a dimension that has a one-to-many relationship with the lower level of the dimension.
Here is the case:
Dimension: Employee
Attribute: Immatriculation
I have 3 source tables : Employee, Language and LanguageLevel.
One employee can have multiple immatriculation codes.
Each immatriculation has a number, start_date, expiration_date.
How can I model this case ?
You need to create Immatriculation-Dimension and use a foreign key on the many side (Immatriculation) of the relationship that linkes back to the one side(Employee). This gives Primary Key- Foreign Key relationship.
Here's a similar case. One book can have multiple authors (in order for this to be a one-to-many relationship one author can only be related to one book. Otherwise it would be a many-to-many relationship..):
CREATE TABLE dbo.Book
(
Pk_Book_Id INT PRIMARY KEY,
Name VARCHAR(255),
ISBN VARCHAR(255)
);
CREATE TABLE dbo.Author
(
Pk_Author_Id INT PRIMARY KEY,
FullName VARCHAR(255),
MobileNo CHAR(10),
Fk_Book_Id INT FOREIGN KEY REFERENCES Book(Pk_Book_Id)
);
INSERT INTO Book VALUES (1, 'Let is Snow', 'ISBN3030303');
INSERT INTO Book VALUES (2, 'Three Cups of Tea','ISBN638242');
GO
INSERT INTO dbo.Author VALUES(100,'John Green','30303',1);
INSERT INTO dbo.Author VALUES(101,'Maureen Johnson','4343',1);
INSERT INTO dbo.Author VALUES(102,'Lauren Myracle','76665',1);
INSERT INTO dbo.Author VALUES(103,'Greg Mortenson','6434',2);
INSERT INTO dbo.Author VALUES(104,'David Oliver Relin','72322',2);
GO
SELECT * FROM dbo.Book;
SELECT * FROM dbo.Author;
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I have a table with a xml column, I need to modify a few fields in the XML for every row. The new values should be unique to that entry, I want to do that by appending the primary key (ID int) to the value in the fields.
For instance: I inserted the rows into a temp table. For simplicity, assume the table only has two columns: payload (XML), id (INT, primary key)
UPDATE #Temp
SET payloadXml.modify('replace value of (/abc/customer/contact/name[#part=("first")]/text())[1] with "hello"')
FROM #Temp
This will replace the first name field with hello. But I want to append the id of that row to this field. I tried sql:variable, but to no avail. Is this even possible?
You can use sql:column to reference a relational column in your XML DML, eg
drop table if exists #temp
go
create table #temp(id int identity primary key, payloadXML xml)
go
insert into #temp(payloadXml) values ('<abc><customer><contact><name part="first">foo</name></contact></customer></abc>');
insert into #temp(payloadXml) values ('<abc><customer><contact><name part="first">foo</name></contact></customer></abc>');
insert into #temp(payloadXml) values ('<abc><customer><contact><name part="first">foo</name></contact></customer></abc>');
WITH q as
(
select *, concat('hello ', id) new_name
from #Temp
)
UPDATE q
SET payloadXml.modify('replace value of (/abc/customer/contact/name[#part=("first")]/text())[1]
with sql:column("new_name")')
select payloadXML from #temp
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I have some studentIDs that are missing some characters from the end. I need to find the closest match (correct ID number) from the Student table.
My script below is taking time to do as I have many students.
Please advise on a better way. I would like to add all incomplete IDs and get the correct one like
if studentID like ('JG853102%','SE686104%','SE686104%')
then get the closest match from my table.
SELECT First Name, Surname, StudentID
FROM StudentTable
WHERE StudentID like 'JG853102%'
OR StudentID like 'SE686104%'
OR StudentID like 'SE686104%'
The query you have is SARGable, however, as I mentioned in the comments the WHERE can never be true. You are checking that the value of StudentID starts with both 'JG853102' and 'SE686104'. This is obviously impossible as a string cannot start with two completely different sets of characters. You therefore most likely want an OR.
The reason the query is slow, however, is likely due to a lack any type of indexing. On a table with the name StudentTable and a column with the name StudentID one would assume that this is your PRIMARY KEY, which means it would be indexed already. This strongly suggests it is not. Based on the value though it doesn't look like it's an always ascending value, meaning that it could likely not be a good candidate for a CLUSTERED INDEX. If it is always ascending, then creating your PRIMARY KEY as a CLUSTERED one would likely make the query far better:
ALTER TABLE dbo.StudentTable ADD CONSTRAINT PK_StudentTable PRIMARY KEY CLUSTERED (StudentID);
As the CLUSTERED INDEX automatically includes all columns in the table, then it'll be a covering index for your columns First and Surname as well.
If the value isn't always ascending, then you want to create a separate index. For what we have, that would minimally be the following:
ALTER TABLE dbo.StudentTable ADD CONSTRAINT PK_StudentTable PRIMARY KEY NONCLUSTERED (StudentID);
CREATE INDEX IX_StudentTable_StudentID ON dbo.StudentTable (StudentID) INCLUDE (First, Surname);
If you have more columns in your table StudentTable then I would INCLUDE all of those if you can.
Finally, you might find that a Table Variable or VALUES construct with an EXISTS might be more performant than an OR. That would look like the following:
--VALUES
SELECT First AS [Name],
Surname,
StudentID
FROM dbo.StudentTable ST
WHERE EXISTS (SELECT 1
FROM (VALUES('JG853102%'),
('SE686104%'))V(StudentID)
WHERE ST.StudentID LIKE V.StudentID);
--Variable
DECLARE #IDs table (StudentID varchar(10));
INSERT INTO #IDs
VALUES('JG853102%'),
('SE686104%');
SELECT First AS [Name],
Surname,
StudentID
FROM dbo.StudentTable ST
WHERE EXISTS (SELECT 1
FROM #IDS I
WHERE ST.StudentID LIKE I.StudentID);
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have a USERS table and an EMPLOYMENT table which links multiple employments to a single user. How can I store the current employment for the user with the constraints that they might not have a current employment, and also they can have only one current employment.
Would a field in the employment table isCurrent work as this by default has no constraints on there only being one current employment?
Another preferred alternative I considered is to have a USER_CURRENT_EMPLOYMENT table which links a user to an employment, however again what constraints would I require for this to work?
As mentioned I am using postgresql but am more curious as to how this relationship should work regardless of language.
Use a unique index and the where predicate to enforce uniqueness on user and his/her last day of employment (which is nullable). This will ensure only one row per user has a NULL value in last_day.
"create unique index idx_current_employer on employment (user_id, (last_day IS NULL)) WHERE last_day IS NULL;"
Here is a complete script to illustrate how to use it:
drop table if exists users;
drop table if exists employment;
create table users
(user_id int not null primary key,
user_name varchar(30) not null)
;
create table employment
(id SERIAL PRIMARY KEY,
user_id int not null,
employer_id int not null,
last_day date null)
;
--insert joe and his previous 2 employers
insert into users
values(1,'Joe');
insert into employment (user_id, employer_id, last_day)
values(1,1,'20150831');
insert into employment (user_id, employer_id, last_day)
values(1,2,'20200831');
--unique index
create unique index idx_current_employer on employment (user_id, (last_day IS NULL)) WHERE last_day IS NULL;
--insert Joe's current employer (null last day)
insert into employment (user_id, employer_id, last_day)
values(1,3,null);
--this one fails - can't insert another employer with null last day
insert into employment (user_id, employer_id, last_day)
values(1,6,null);
--set last day of previous employer first
update employment
set last_day = '20201006'
where user_id = 1
and last_day is null
;
--now insert succeeds
insert into employment (user_id, employer_id, last_day)
values(1,6,null);
--list all employment
select user_id, employer_id, last_day, case when last_day is null then True else False end as is_current
from employment
order by 1, 4 desc, 3 desc
;
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
How can an algorithm is written to find Primary Keys and Foreign Keys of a relation ?
Given parameters are name of relation, degree of relation and an array of the attributes(a primary key may include more than one attribute)
I think if an attribute is referenced than it is primary key. and the attirbute that references is FK
I would make a list of columns that contain no redundancies and no null cells as possible primary keys. I suppose one fast way to detect them would be to attempt to declare the column as a PK and see if there are errors. Another approach would be a group by:
select column_name, count(*) c from table_name
where column_name is not null
group by c
having c <> 1
If column_name of table_name is plausibly a primary key, the query above should produce no rows.
As for foreign keys, try this:
select column_name from table_name
except
select other_column from other_table
This should return an empty set if other_column of other_table has column_name of table_name as a foreign key.
As for automating the above tests over all the tables and each of their columns, I can't help there as my SQL vocabulary doesn't include Microsoft.
Note that passing the tests above is a necessary but not sufficient condition for a column to be a key. Determining which columns should be keys is as much a matter of intuition as algorithms, and if your starting point is taming a messy collection of raw data there may be columns that fail the tests but should nevertheless be keys.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
A patient can select many tests, and a test can be selected by many patient.
Then what would be the structure of these tables and how the relationship can be established between them?
your table structure should be below
PatientTable
PatientId int Primary Key,
PatientName varchar(50),
EmailId varchar(50)
Password varchar(50)
TestTable
TestId int Primary key,
TestName varchar(50)
PatientTestTable
PatientId int FK(PatientTable)
TestId int FK (TestTable)
This way you can give relationship to two tables. you need to understand funamental of RDBMS.
You will probably need 3 tables, Patient table, Test Table and PatientTest Table
with PatientID as foreign key fro Patient table and TestId as foreign key from Test table and you can add any other column ( like TestDatetime, TestResult ...)