Need a help o create table structure sql? - sql

I have to create following table structure for a group.
1 member can join many groups
1 group can have only 1 owner member
need to design these two tables member and group?
i tried like
MemberTable
Mid(PK) Mname MAddress
1m aaa IND
2m bbb UK
GroupTable
Gid(PK) Mid(FK) Gname
1g 1m GROUP1
2g 1m GROUP2
3g 2m GROUP3
is this a correct approach or should i create a 3rd table?

table Member
id, memberName
table Group
id, groupName, OwnerId
with a FK from OwnerId to table member(id)
relational table MembersxGroup
memberId, groupId
with both FKs from memberId and groupId to respective tables
and a unique non clustered index covering both columns

Related

Own id for every unique name in the table?

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

How to copy information in SQL from one table to another

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);

How to compare two tables row by row in SQL

I have two temporary tables with single column
Table 1
MaXAge (Contains maximum age of each kind)
-----------
15
15
11
Table 2
KGroup (Contains each kind)
--------------------------------------------------
Cat
Dog
Parrot
AND another Table Pets with fields
PetID Name Kind Gender Age OwnerID
NOW, I want to display name of animals with maximum age group by kind
You can do this without using any temp tables
SELECT name, age
FROM pets p
JOIN (SELECT kind, MAX(age) max_age FROM pets GROUP BY kind) AS sub ON sub.kind = p.kind AND sub.max_age = p.age

One SQL statement for counting the records in the master table based on matching records in the detail table?

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;

How can I insert records from a table to another table order by the specific column value?

Does anyone know how can I insert records from a table to another table order by the specific column value?
For Example:
I have the following table:
tableA:
record_id int,
name varchar(100),
nickname(100),
chain_id int (PK),
chain_n int,
count int,
create_date datetime
tableB:
record_id int,
name varchar(100),
nickname(100),
chain_id int (PK),
chain_n int,
create_date datetime
I have the following value for tableA:
record_id name nickname chain_id chain_n count create_date
1 Test One 1 1 2 2013-06-06
2 Test Two 2 1 5 2013-06-06
3 Test Three 3 1 3 2013-06-06
I using the following scrip to insert the data into thableB
INSERT INTO tableB
(
record_id,
name,
nickname,
chain_id,
chain_n,
create_date
)
SELECT
(
record_id,
name,
nickname,
chain_id,
chain_n,
create_date
)
FROM tableA
ORDER BY count DESC
I expecting the data will insert into tableB like the following:
record_id name nickname chain_id chain_n create_date
2 Test Two 2 1 2013-06-06
3 Test Three 3 1 2013-06-06
1 Test One 1 1 2013-06-06
However, the result was as following still order by the chain_id
record_id name nickname chain_id chain_n create_date
1 Test One 1 1 2013-06-06
2 Test Two 2 1 2013-06-06
3 Test Three 3 1 2013-06-06
Does anyone know how can manage to insert the records order by the count instead
It seems that record_id is your primary key and thus default ordering is done by that. That's why your output is same as in tableA. Just use ORDER BY in SELECT clause for tableB.
Inserting records into a table in particular order doesn't make much sense to me becuase ORDER BY doesn't actually influence the way the data is written to your drive. All records will be inserted in the order of your clustered index. In any case if you want to query data from a table ordered by some field you should explicitly state it in the ORDER BY clause even if you want your data ordered by clustered index columns. Although all data is meant to be ordered by clustered index by default it's still up to SQL Server engine to define the best execution plan and change the order if required if you don't specify it explicitly in the ORDER BY clause.