SQL Insert into with select from multiple tables - sql

I have the following 3 tables, Data_Excel contains the names, address, city and source of person; Person table has the name and ID; I need to insert into person_location the address source, address, city and ID...where ID comes from person table and name that exist against the id should be matched in the data_excel table to get all the details

Take a look at this very similar question which should provide the information you need to apply to your own problem.

The error is probably from this part of the query A.name, A.ID in (Select[...]
You can try..
INSERT INTO person_location
SELECT A.ID,A.P_name,source,P_address,P_city,P_country from data_excel de, person A where A.name = de.c_name;
If you need the ID > 6566 condition, you can add it at the end.
INSERT INTO person_location
SELECT A.ID,A.P_name,source,P_address,P_city,P_country from data_excel de, person A where A.name = de.c_name and ID > 6566;

Related

SQL connecting 3 seperate tables using procedures

I'm struggling with SQL a bit, so far I have 3 tables:
CUSTOMER
id,
name,
surname,
gender,
birthdate
GENDER
id,
gender
ADRESS
id,
country,
city
I need to create a procedure on connecting these 3 tables into a big one, so it would have (customer id, name, gender, country)
I know that I have to use joins but I am so unfamiliar with SQL.
You should just use a JOIN we use a JOIN on 2 or more tables in order to fetch some common attributes related values of one table that exists in other as together. So, here the sql then would look like. Also you dont require the gender seperate table as you have gender already present in your customer table
Select
c.id, c.name, c.gender, a.country
From CUSTOMER c
Join
Address a
On c.id =a.id

what is the proper union or sql construct to resolve these 2 datasets?

I have a table UserParent:
Id, FirstName, LastName
I have a table UserChild:
Id, ParentUserId (FK), ChildAttributeX
I have the following sample SQL:
SELECT Id, 0 ChildUserId, FirstName, LastName, NULL FROM UserParent
UNION
SELECT ParentUserId, Id, FirstName, LastName, ChildAttributeX FROM UserChild
Some Users may exist in both tables. All Users are stored with basic info in UserParent although some Users who have ChildAttributeX will have a FK ref to the UserParent in UserChild along with the ChildAttributeX in UserChild.
How can I resolve this as part of a UNION or some other SQL technique so all Users are included in the result set, without duplicate users?
I think this is what you are looking for. If all records must exist in parent table, this will return all records from parent, and any record that exist in child table, but only unique records (DISTINCT does that).
SELECT DISTINCT UP.ID, UP.FirstName, UP.LastName
FROM UserParent UP
LEFT OUTER JOIN UserChild UC ON UP.ID = UC.ParentUserID
If you are looking for all the records present in both table, you can try below query:
SELECT
coalesce(UP.Id,UC.ParentUserId),
0 ChildUserId,
(UP.FirstName,UC.FirstName),
(UP.LastName,UC.LastName),
NULL FROM
UserParent UP
FULL OUTER JOIN
UserChild UC
ON UC.ParentUserId = UP.ID

How to write a Sql query for retrieving one row from duplicate rows?

i have a User table which has many users but some users are having same first name and Last Name but only one user will have status active . So my requirement is if the user is unique i need the user regardless of Status but if the user is duplicate i need the record having status active.
How can i achieve this in SQL server?
Sorry For the confusion here is the example of User table
my result table should be
Here Steve Jordan is having 2 records so i need the record having status 1
and for records having distinct First name and last name i need all the records regard less of status.
Note : I have a user id as primary key but i am joining on first name and last name because other table doesn't have user id.
SELECT UserId, FirstName, LastName, Status FROM (
SELECT *
, ROW_NUMBER() OVER (PARTITION BY FirstName, LastName
ORDER BY Status DESC) AS rowNum
FROM [User]
) u
WHERE u.rowNum = 1
This essentially groups by first and last name, orders by Status so that active are higher priority, and takes only one of each unique first/last name combination. This ensures that each each unique first/last name combination is in the result set only once, and if there are multiples, the active one is the one returned. If a name combination has multiples, but they are all not active, then only one is returned, chosen arbitrarily.
Ideally, you should have the User ID PK in both tables, as this is much stronger relationally.
EDIT: A bit more complex, but this should give you what you're looking for.
SELECT *
FROM YourOtherTable A
JOIN Users B
ON A.FirstName = B.FirstName AND A.FirstName = B.FirstName
LEFT JOIN
(
SELECT FirstName, LastName FROM User GROUP BY FirstName, LastName HAVING COUNT(FirstName) = 1
) C
ON B.FirstName = C.FirstName AND B.LastName = C.LastName
WHERE B.Status = 1 OR C.FirstName IS NOT NULL
I didn't get you question. But, as per your subject line. It seems like you want the record, which is active, if record is duplicate.
select T.* from yourTable T INNER JOIN (select user, count(*) cnt FROM yourTable GROUP BY user) A ON A.user=T.user
WHERE A.cnt>1 and T.status='A';
If it wasn't your requirement. Then, I would ask you to share your table structure and expected output to understand better.

Select duplicated field name

If I have the following scenario
Table that store people
id_person, name, age (...)
And a table that stores address of people
id_address, id_person, city
If I run a query like this
select * from people P left join address A on P.id_person = A.id_person
I'm getting id_person === null in result set (because there IS a person, but no address has been recorded it, which is fine).
The null is comming from the table address. Is it possible to solve this without doing select field1, field2, field3 ... (lots os fields)?
Example
Person
id_person Name
1 John
2 Steve
Address
id_address id_person city
1 1 'AnyCity'
When I run a query like this
select * from people P left join address A on P.id_person = A.id_person
where P.name = 'Steve'
His id_person is returning null
You mean you only want the id_person from the people table, not from the address table (which sometimes is NULL)?
select p.id_person, p.name, p.age, a.id_address, a.city
from people P left join address A ON P.id_person = A.id_person
Is it possible to solve this without doing select field1, field2, field3 ... (lots os fields)
No - you either use * or identify the fields. You could select all fields from one table and then cherry pick from the other table:
select P.*, A.address, A.City, ...
from people P
left join address A where P.id_person = A.id_person

SQL Multiple Duplicate Row Detection

I'm trying to determine a correct way to isolate rows within a table that have the same values in 2 columns.
There are two tables, one (Name) with the person's names and IDs, and the other one (Nation) with people's IDs and their nations. I join the two tables with inner join, and now the new table columns consist of an ID, first name, last name, and nation. If I want to find pairs of people who have the same last name and are from the same nation, why isn't
select ID, FName, LName, Nation
from (Name inner join Nation on Name.ID = Nation.ID)
group by Name, Nation
having count(Name) > 1 and count(Nation) > 1
working?
I'm aiming for the result to be a table with columns:
ID -------First--------------- Last ---------Nation
where the last names and nations will be identical pairs while first names will be different.
I feel like the group by part isnt appropriate, but is there even an alternate way? Thanks for any help.
If you are using MS SQL Server:
select
*
from
(
select
Name.*,
Nation.Nation,
cnt = count(*) over(partition by LName, Nation)
from Name
join Nation on Nation.ID = Name.ID
) t
where cnt > 1
Try this:
SELECT * FROM (
SELECT Name.ID, Name.FName, Name.LName, Nation.Nation
FROM Name
INNER JOIN Nation ON (Name.ID = Nation.ID)
) a
INNER JOIN (
SELECT Name.ID, Name.FName, Name.LName, Nation.Nation
FROM Name
INNER JOIN Nation ON (Name.ID = Nation.ID)
) b ON (a.LName = b.LName AND a.Nation = b.Nation)
WHERE a.ID < b.ID
As Simon Righarts hinted, something's not right with the design.
Scenario 1)
If a name can have multiple nations, you would have 3 tables implementing an n:m relationship.
CREATE TABLE name (name_id int, name text, ...);
CREATE TABLE nation (nation_id int, nation text, ...);
CREATE TABLE nationality (name_id int references name(name_id)
,nation_id int references nation(nation_id)
... );
Query for the scenario:
SELECT a.name_id, a.fname, a.lname, n.nation
FROM name a
JOIN nationality na USING (name_id)
JOIN nation n USING (nation_id)
JOIN (
SELECT a.lname, na.nation_id
FROM name a
JOIN nationality na USING (name_id)
GROUP BY 1,2
HAVING count(*) > 1) x USING (lname, nation_id)
Scenario 2)
If a name can only have one nation, there would be a column nation_id in the table name:
CREATE TABLE name (name_id int
,name text
,nation_id int references nation(nation_id), ...);
CREATE TABLE nation (nation_id int, nation text, ...);
Query for this scenario:
SELECT a.name_id, a.fname, a.lname, n.nation
FROM name a
JOIN nation n USING (nation_id)
JOIN (
SELECT a.lname, a.nation_id
FROM name a
GROUP BY 1,2
HAVING count(*) > 1) x USING (lname, nation_id);
All multiple occurrences are included here, not just "pairs" - assuming you meant that.
Your actual description doesn't fit either scenario.