I need to build a query to copy information in a column from one table to a column in another table.
This is how the tables looks like:
People:
PersonId
Name
StatusId
1
John
2
Jenny
3
Steve
Assignments:
AssignmentId
Country
PersonId
1
UK.
1
2
USA
3
Status:
StateId
Name
1
Busy
2
Free
There is a relationsihp between the People and Assignments tables: PersonId on the Assignments table is a FK. The People table has a relationship with the Status table through the FK StatusId. What I need to do is populate the StatusId on the table People with the StatusId from the table Status if the person in the table People exists on the table Assignments.
On the sample above both John and Steve are in the Assignments table, in this case theirs StatusId on the table People should be set to 1.
I was trying to do it with this:
update People
set StatusId = 1
where PersonId IN (
select PersonId
from Assignments
where Assignments.PersonId = People.PersonId
)
but as you can see I am hardcoding the StatusId what will not works. Is there some way to get the StatusId based on the result of the select? Or is there another way to get the StatusId?
If you want to refer to it by "name", you can use a subquery:
update People
set StatusId = (select s.StatusId from status s where name = 'Busy')
where PersonId IN (select a.PersonId from Assignments a where a.PersonId = People.PersonId);
Related
Is it possible to make a table that has like auto-incrementing id's for every unique name that I make in the table?
For example:
ID NAME_ID NAME
----------------------
1 1 John
2 1 John
3 1 John
4 2 Mary
5 2 Mary
6 3 Sarah
7 4 Lucas
and so on.
Use the window function rank() to get a unique id per name. Or dense_rank() to get the same without gaps:
SELECT id, dense_rank() OVER (ORDER BY name) AS name_id, name
FROM tbl;
I would advise not to write that redundant information to your table. You can generate that number on the fly. Or you shouldn't store name redundantly in that table, name would typically live in another table, with name_id as PRIMARY KEY.
Then you have a "names" table and run "SELECT or INSERT" there to get a unique name_id for every new entry in the main table. See:
Is SELECT or INSERT in a function prone to race conditions?
First add the column to the table.
ALTER TABLE yourtable
ADD [UID] INT NULL;
``
ALTER TABLE yourtable
ADD constraint fk_yourtable_uid_id foreign key ([UID]) references yourtable([Serial]);
Then you can update the UID with the minimum Serial ID per Name.
UPDATE t
SET [UID] = q.[UID]
FROM yourtable t
JOIN
(
SELECT Name, MIN([Serial]) AS [UID]
FROM yourtable
GROUP BY Name
) q ON q.Name = t.Name
WHERE (t.[UID] IS NULL OR t.[UID] != q.[UID]) -- Repeatability
Given this scenario:
I have 2 tables, 1 named Books and the other Customers that look like this -
Books
----------
CustomerId
BookTitle2
Customers
----------
CustomerId
FirstName
LastName
BookTitle
The customers table has a BookTitle field that has the name of books the customer acquired from another Source (or they could be books they can manual enter into that field)
The Books table can have the same Customer as in the Customers table but the book in that table is from a publisher entered book.
How would I write an SQL query to acquire all the records in the customer table for a specific Customer based on the CustomerId and add the record(s) from the Books table to the returned record set?
The end result would look similar to this:
CustomerId | FirstName | LastName | BookTitle
CustomerId | FirstName | LastName | BookTitle2
I could create empty pseudo fields in the Books table to correspond to the Customers table and perform a UNION but I would want to be able to filter on a specific customer ID in one place in the query to acquire the combination of records from both tables
Try this:
Select CustomerId, FirstName, LastName, BookTitle
from Customers
where ...
UNION
Select CustomerId, '' as FirstName, '' as LastName, BookTitle2 as Booktitle
from Books
where...
Note that WHERE condition in the above query is optional and you can use them appropriately.
Hope this helps. Please share your thoughts if it solved your problem.
I have a table groups
group_id | name_group
1 ISI
2 IZI
And a table students
id | first_name | last_name | group_id
6 Bob Surname1 1
17 John Surname2 2
How can I delete all information from student table by using groups.name?
i.e. I need query which select all students with the same group_id which is equivalent to name.
group_id 1 = 'ISI'
group_id 2 = 'IZI'
And a query must delete exactly by name.
You can use this query
Delete from Students where group_id=(Select group_id from groups where name_group='ISI');
This all the records with the group_id of 1 (via group_name='ISi').
There are different ways. A simple one, could be selecting the Id of the group and deleting from there. Example:
DECLARE
#name as nvarchar(20) = 'myName'
-- we display the data just for check
SELECT s.*, g.group_id
FROM students s ON g.group_id = s.group_id
WHERE g.name_group = #name
--we look the group id and delete the matches with students
DELETE
FROM students
WHERE group_id in (SELECT group_id FROM groups WHERE name_group = #name)
PD: This basic approach could work on both: MySQL and MSSQL.
I have three table look like
1.Table Branch
BranchID = FK
Name
Address
Contact
2.Table Staff
Staff_ID = FK
Name
Address
Gender
Contact
Supervisor_ID = if does not have a supervisor then NULL
BranchID
3.Table Manager
Staff_ID = FK
Name
Address
Gender
Contact
BranchID
I would like to produce a listing showing the staff distribution at each branch. Include the branch number, manager name, total number of supervisors, and total number of male and female staff for each branch.
How do I retrieve a result set as above using an sql statement?
Below is my query
select Manager.Name,Branch.BranchNum,count(case when Supervisor_ID is null then 1 else null end) as NumberofSupervisor,count(case when Staff.gender='Male' and Supervisor_ID is not null then 1 else null end ) as Male, count(case when Staff.gender='Female' and Supervisor_ID is not null then 1 else null end)as female from Branch join Manager on Branch.BranchNum=Manager.BranchNum join Staff on Branch.BranchNum=Staff.BranchNum group by Branch.BranchNum
I get this error Column 'Manager.Name' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Could you please guide me?
Thank you.
I have the following master table called Master and sample data
ID---------------Date
1 2014-09-07
2 2014-09-07
3 2014-09-08
The following details table called Details
masterId-------------Name
1 John Walsh
1 John Jones
2 John Carney
1 Peter Lewis
3 John Wilson
Now I want to find out the count of Master records (grouped on the Date column) whose corresponding details record with Name having the value "John".
I cannot figure how to write a single SQL statement for this job.
**Please note that join is needed in order to find master records for count. However, such join creates duplicate master records for count. I need to remove such duplicate records from being counted when grouping on the Date column in the Master table.
The correct results should be:
count: grouped on Date column
2 2014-09-07
1 2014-09-08
**
Thanks and regards!
This answer assumes the following
The Name field is always FirstName LastName
You are looking once and only once for the John firstname. The search criteria would be different, pending what you need
SELECT Date, Count(*)
FROM tblmaster
INNER JOIN tbldetails ON tblmaster.ID=tbldetails.masterId
WHERE NAME LIKE 'John%'
GROUP BY Date, tbldetails.masterId
What we're doing here is using a wilcard character in our string search to say "Look for John where any characters of any length follows".
Also, here is a way to create table variables based on what we're working with
DECLARE #tblmaster as table(
ID int,
[date] datetime
)
DECLARE #tbldetails as table(
masterID int,
name varchar(50)
)
INSERT INTO #tblmaster (ID,[date])
VALUES
(1,'2014-09-07'),(2,'2014-09-07'),(3,'2014-09-08')
INSERT INTO #tbldetails(masterID, name) VALUES
(1,'John Walsh'),
(1,'John Jones'),
(2,'John Carney'),
(1,'Peter Lewis'),
(3,'John Wilson')
Based on all comments below, this SQL statement in it's clunky glory should do the trick.
SELECT date,count(t1.ID) FROM #tblmaster mainTable INNER JOIN
(
SELECT ID, COUNT(*) as countOfAll
FROM #tblmaster t1
INNER JOIN #tbldetails t2 ON t1.ID=t2.masterId
WHERE NAME LIKE 'John%'
GROUP BY id)
as t1 on t1.ID = mainTable.id
GROUP BY mainTable.date
Is this what you want?
select date, count(distinct m.id)
from master m join
details d
on d.masterid = m.id
where name like '%John%'
group by date;