SQL many-to-many JOIN - sql

i am having difficulties joining two tables.
I have the tables
Customer_table
---------------------------------------
| CustomerId(PK) | Firstname | Lastname |
---------------------------------------
CustomerInterest_table
----------------------------------------
| CustomerId(PK,FK) | InterestId(PK,FK) |
----------------------------------------
Interest_table
-------------------------------
| InterestId(PK) | InterestInfo |
-------------------------------
What i want to do is to select every customer, and join the interests with the FK reference on the table.
Ultimately i want to fetch a result containing the customers fetched from the customer table, and the customer interests fetched from the CustomerInterest_table.
Id like to build objects like this
{
customerId : 'Id12345,
firstname : 'John',
lastname : 'Doe',
interests : [{interestId : 1, interestInfo : 'Apples'}]
}
How would i go about fetching and joining the tables ?
Any help greatly appreciated.

Database design (First Normal Form) suppose that column should be simple type, in you case it mean no-array. Instead you can fetch desired from multiple selected rows:
SELECT customerId, firstname, lastname, interestId, InterestInfo
FROM Customer_table c
INNER JOIN CustomerInterest_table tc
ON c.customerId = tc.customerId
INNER JOIN Interest_table i
ON tc.InterestId = i.InterestId
ORDER BY customerId
Last ORDER BY allows you force order of rows so interests of the same customer will follow one by one.
Alternatively if customer MAY not have interests you can leverage LEFT JOIN (then two columns interestId, InterestInfo will be NULL)
SELECT customerId, firstname, lastname, interestId, InterestInfo
FROM Customer_table c
LEFT OUTER JOIN CustomerInterest_table tc
ON c.customerId = tc.customerId
INNER JOIN Interest_table i
ON tc.InterestId = i.InterestId
ORDER BY customerId
UPDATE
Alternatively (if you really want everything in single column for any cost) you can cast result to XML datatype, Then Last column will compose complex XML:
SELECT customerId, firstname, lastname
, [Name]
, (STUFF((SELECT CAST(', ' + interestId AS VARCHAR(MAX) + ':' + InterestInfo)
FROM Interest_table i
WHERE tc.InterestId = i.InterestId
FOR XML PATH ('')), 1, 2, '')) AS interests
FROM Customer_table c
INNER JOIN CustomerInterest_table tc
ON c.customerId = tc.customerId
(p.s. sorry syntax is not checked for correctness)

Related

SQL to concatenate two columns and join two tables

Table person:
| id | f_name | l_name |
Table sales:
| id | amount | date | itemname |
I have a problem joining the two tables which concat f_name and last_name as fullname column, and joining with table sales. Here id is same on both tables.
Output:
| itemname| date |fullname |
What I have tried:
select *
from
(select
concat(f_name, l_name) as fullname
from
tblperson) p
left join
select itemname, date
from table sales s on s.id = p.id
It should actually be
SELECT table_sales.*, concat(table_person.f_name, table_person.l_name) as fullname
FROM table_person
LEFT JOIN table_sales
ON table_person.id = table_sales.id
have not tested this but that is the syntax
you're missing a field like person_id in your sales table (which references the id field in the person table). You can then use a join to properly join the data together.
You are so close. Try this
select p.*,concat(f_name,l_name)as fullname, s.itemname,s.date, s.amount
from person p left join
sales s on s.id=p.id
Here ia good read on sql join.
https://www.w3schools.com/sql/sql_join.asp

SQLquery to merge multiple row values into single row separated by delimiters &display along with other fields

Please help me with the below scenarios.
I have 3 tables where i need to display a single record for one fileno with multiple values of same field should be displayed with delimiters by join all three tables.
OrdersTable (orderguid is Primary key ) and guids are referencing in buyer and property tables
I have 2 address referring same fileno
I have 2 BuyerName referring same fileno
so the o/p should be
fileno address1,address2 zip state buyername,buyername
Orders Table
Orderguid (PK) fileno
8C25-00F768 100
2C25-00D695 200
Property Table
Address Zip State OrderGuid(FK)
Street no 1 122235 TX 8C25-00F768
Street no 2 122235 TX 8C25-00F768
Buyers Table
BuyerName OrderGuid (FK)
Dennis Richard 8C25-00F768
Levis Richard 8C25-00F768
output :
fileno Address Zip State BuyerName
100 Street no 1 ; Street no 2 122235 TX Dennis Richard; Levis Richard
200 null null null null
Your query should be like this :
EDIT : ( I highly recommend to avoid merging multiple values into a single row)
;WITH CTE AS (
select o.fileno ,
stuff((SELECT ';' + pr.Address from Property pr
inner join Orders o on o.Orderguid=p.Orderguid
FOR XML PATH ('')), 1, 1, ''
) AS Address
,
stuff((SELECT ';' + b.BuyerName from Buyer b
inner join Orders o1 on o1.Orderguid=p.Orderguid
FOR XML PATH ('')), 1, 1, ''
) AS Buyers
,p.Zip
,p.State
, ROW_NUMBER() OVER (PARTITION BY o.Orderguid ORDER BY o.Orderguid ) rn
from Orders o
left join Property p ON p.Orderguid=o.Orderguid
left join Buyer b ON b.Orderguid=p.Orderguid
group by o.fileno, p.Address, p.Zip, p.State,p.Orderguid,o.Orderguid )
select * from CTE
where rn=1
See results from here

How can I join multiple tables on the same auto generated integer from one "table"?

I want to create a random selected cross-joined table which auto increments its own id and joins on it.
Let's say my tables looking like this.
Person
Firstname, Lastname
Hans | Müller
Joachim | Bugert
Address
City, Street, StreetNumber
Hamburg | Wandsbeckerstr. | 2
Berlin | Konradstraße | 13
Now I want to join the tables with a auto generated ID and they should be random selected.
The final table should look like this
ID,Firstname,Lastname, City, Street, StreetNumber
1 |Hans|Bugert|Berlin|Wandsbeckerstr|2
2|Joachim|Müller|Hamburg|Konradstraße | 13
What I already tried or used:
Here I auto-generate the ID where I want to join the tables on
select GENERATED_PERIOD_START as ID FROM SERIES_GENERATE_INTEGER(1,1,10)
The problem is cross join and inner join isn't working for me because it always joins everything with everything or its not joining on the same ID.
SELECT Person."Firstname", Person."Lastname", Address."City",Address."Street", Address."StreetNumber"
FROM
( select GENERATED_PERIOD_START as ID FROM SERIES_GENERATE_INTEGER(1,1,10)
) autoGenID
inner JOIN
(select "Firstname" ,"Lastname" FROM Person ORDER BY RAND()) Person
inner JOIN
(select "City", "Street", "StreetNumber", FROM Address ORDER BY RAND()) Address
JOIN ON autoGenID."ID"=?????
Here is my problem I can't just select random data and select that on my auto generated ID.
Thanks for your help or ideas how to solve this!
I think you want:
SELECT p."Firstname", p."Lastname", a."City", a."Street", a."StreetNumber"
FROM (SELECT p.*,
ROW_NUMBER() OVER (ORDER BY RAND()) as seqnum
FROM Person p
) p JOIN
(SELECT a.*,
ROW_NUMBER() OVER (ORDER BY RAND()) as seqnum
FROM Address a
) a
ON p.seqnum = a.seqnum;

Combine multiple row values into one row

I have a result set that should be pulled into a report as one line. However, there can be multiple buyers associated to an order and these buyers are represented as a new row in the database. So for instance, I have the following...
SELECT
O.OrdersID
,BS.LastName
FROM
Orders O
LEFT JOIN
BuyerSeller BS ON O.OrdersID = BS.OrdersID
If there are multiple buyers, it will return the following result set as follows:
OrdersID | LastName
----------------------
1 | Tester1
1 | Tester2
1 | Tester3
I'd like it to return as the following (separated by columns):
OrdersID | LastName
---------------------------------------
1 | Tester1, Tester2, Tester3
Thanks for the assistance.
Here is your Answer.
SELECT DISTINCT Ord.OrderID , substring
((SELECT ',' + BS.LastName AS [text()]
FROM Orders O LEFT JOIN BuyerSeller BS ON O.OrderID = BS.OrderID
ORDER BY O.OrderID FOR XML PATH('')), 2, 1000) LastName
FROM Orders ord
This will return the expected output.
To accomplish this in SSRS you would need to
Create a table with OrdersID as Row group
Make sure there is no detail section inside the group. If there is one delete it without deleting the rows.
Write this experession for LastName:
=Join(Lookupset(Fields!OrdersID.Value, Fields!OrdersID.Value, Fields!LastName.Value, "myDataSet"), ", ")
Remember SSRS is case sensitive.

Select Query Joining 3 Tables

I've 3 Tables
Personel : id, name
Department : id, name
Match_Dept_Per : dept_id, pers_id, workInfo
Foreign Keys :
dept_id --> Department.id
pers_id --> Personel.id
Example Data :
Personel :
1, Emir Civas
2, Sercan Tuncay
Department :
1, Sales
2, Planning
Match_Dept_Per :
1,1,Manager
What I'm trying to do is, listing peoples names, their department names and workInfos like:
ID | Pers. Name | Dept Name | Work Info
---------------------------------------
1 | Emir Civas | Sales | Manager
I can do this with a simple select query:
select p.id, p.name, d.name, m.workInfo
from personel p, department d, match_dept_per m
where p.id = m.pers_id and d.id = m.dept_id;
Here is sample fiddle of my schema and this query.
However what I need is to display other persons that their id's are not inserted to match_dept_per table. And Set "Unknown" As the Null Values. Like:
ID | Pers. Name | Dept Name | Work Info
------------------------------------------
1 | Emir Civas | Sales | Manager
2 | Sercan Tuncay | Unknown | Unknown
Since I'm Using Match_Dept_Per Table, If Personel ID isn't Added, I can't do anything.
Any suggestions ?
Use left outer join to include all persons even if they are not associated with the other tables:
select p.id,
p.name,
ifnull(d.name, 'Unknown') DepName,
ifnull(m.workInfo, 'Unknown') workInfo
from personel p
left outer join match_dept_per m
on p.id = m.pers_id
left outer join department d
on d.id = m.dept_id
Here is a demo fiddle.
As you seem to use MS SQL, you might need to use isnull() instead of ifnull(). But I would ommit that anyway because I think it's better to have a NULL in the code where you use the data (Java, C#, whatever). You can control the output there.