SQL View - Combine multiple rows into 1 row - sql-server

I am trying to make a new view using in MSSql 2008 from three tables:
Table 1 has customer id and transaction id
Table 1
CustomerID TransactionID
1 1
1 2
Table 2 has Purchases Transaction and Products ID
TransactionID ProductID
1 x
2 y
Table 3 has Products Names
ProductID Name
1 x
2 y
I view I would like to make should show
CustomerID Product Name
1 x, y
When I use the following query:
SELECT table1. CustomerID, table3.Name
FROM table1 LEFT OUTER JOIN
Table2 ON table2. TransactionID = table1.VisitId LEFT OUTER JOIN
Table3 ON table2. ProductID = Table3. ProductID
GROUP BY table1. CustomerID, table3.Name
I get
CustomerID Product Name
1 x
1 y
Thanks in Advance

One way to do this is to use a user defined function, something like:
SELECT table1.CustomerID, dbo.BuildStringOfCustomerProductNames(table1.CustomerID)
FROM table1
And create a user defined function like: dbo.BuildStringOfCustomerProductNames
that takes a customerid as input.
Inside there, you can run a query to loop through the table 2 and table 3 joined records to make a string, and return that.
Off hand I can't think of any other simple way to do it.

Related

Joining tables with where clause dynamically

Table1
ID
WhereField
Value
1
Column1
2
2
Column2
3
Table2
ID
Column1
Column2
Somedata
1
5
2
Some data
2
6
3
Some more data
With the current scenario, I have 2 tables that need to be joined, the second table's field name is defined as value on the first table.
I need to get the data that needs to be joined with a where clause dynamically such as:
select * from Table1 T1
inner join T1.WhereField on T2. "Dynamic where field column"
where T2."Dynamic where field column" = t1.Value
Is this even achieveable?

SQL Server : how to union 3 tables with different number of rows

I have 3 tables with different data and I need to return one table that includes all 3 tables:
Customer
Contacts
Addresses
I want to get the data in only one table and one record with all details like CustomerNumber, Name, City, officeNumber...., like Union
SELECT CU.[Name]
FROM Customers CU
WHERE CustomerNumber = #CustomerId
AND IsDeleted = 0
SELECT AD.City, AD.Street
FROM [Addresses] AD
WHERE CustomerId = #CustomerId
AND IsDeleted = 0
SELECT CO.FullName, CO.OfficeNumber, CO.Email
FROM [Contacts] CO
WHERE CustomerId = #CustomerId
AND IsDeleted = 0
Result:
Number of rows doesn't matter for a union number of columns do.
What do you expect with a union?
I suppose you want you want all information (name address, contact) of customer having Id= #CustomerId
If I am right, you should make 2 join between the 3 tables using CustomerId as join clause
Edit:
https://www.db-fiddle.com/f/uGhtAZAVk64KzgThGekKk6/11
You need to JOIN the tables not UNION them. Please research SQL Server JOIN as there multiple types of joins you can do. In this case you're looking for an INNER JOIN this type of join will only return records when you have matching keys in all the tables. The key in your case is the customer id. You JOIN the tables ON customer id. Your query should look something like this:
SELECT CU.[Name], AD.City, AD.Street, CO.FullName, CO.OfficeNumber, CO.Email
FROM Customers CU
INNER JOIN [Addresses] AD
ON CU.CustomerNumber = AD.CustomerId
INNER JOIN [Contacts] CO
ON CO.CustomerId = CU.CustomerNumber
WHERE CU.CustomerNumber = #CustomerId

Merge 2 tables into 1 single Table in T-SQL

How do I merge 2 tables into 1 table in T-SQL? I tried merging with full outer join which helps in joining 2 tables but with "customer Account" 2 times. I need all the columns from table A and Table B with only once "Customer Account Field" and all the rest of the columns from table A and Table B.ields.
Here is my example in more detail:
Table A - my first Table with 5 columns:
Table B - my second table with 6 columns:
I'm expecting the output like this:
Output with all fields in table A and in Table B but the common field only once:
Thanks a lot.
Add the required(all) columns from t1 and t2 to the select statement
SELECT COALESCE(t1.customeraccount, t2.customeraccount) as customeraccount,
t1.BasicCardType,
t2.MonthlySet
FROM table1 t1
FULL JOIN table2 t2 ON t1.customeraccount = t2.customeraccount;
(Edited based on comments): Join the tables on the CustomerAccount ID field (giving you entries that exist in both tables), then add a union for all entries that only exist in table A, then add a union for entries that only exist in table B. In principle:
-- get entries that exist in both tables
select Table_A.CustomerAccount, TableAField1, TableAField2, TableBField1, TableBField2
from Table_A
join Table_B on Table_A.CustomerAccount = Table_B.CustomerAccount
-- get entries that only exist in table_a
union select Table_A.CustomerAccount, TableAField1, TableAField2, null, null
from Table_A
where Table_A.CustomerAccount not in (select CustomerAccount from Table_B)
-- get entries that only exist in table_B
union select Table_B.CustomerAccount, null, null, TableBField1, TableBField2
from Table_B
where Table_B.CustomerAccount not in (select CustomerAccount from Table_A)

Matching two columns of two tables for a particular value in oracle

Consider there are two tables:
TABLE1 and TABLE2 ,Both of them have same attributes i.e. ID,NAME,CLASS,STATUS.
These two tables has data for all the students in the school...but managed by two independent bodies.
On the basis of unique ID I want to check that for all the students whether the data is same in both the tables.
I would be interested in retrieving the unmatched data in both tables, But don't want the unmatched data where status of a student is 'lefttheschool' in both the tables(and if status is 'lefttheschool'in one table and'present'in other ,it is unmatched and it should be retrieved).
For example:
TABLE1 ID NAME CLASS STATUS
1 A 3 PRESENT
2 B 4 LEFT
3 B 7 LEFT
TABLE2 ID NAME CLASS STATUS
1 A 3 PRESENT
2 C 4 PRESENT
3 B 5 LEFT
RESULT:ID NAME CLASS STATUS ID NAME CLASS STATUS
2 B 4 LEFT 2 C 4 PRESENT
Select all when ID is the same and other attribute is different:
select table1.*, table2.*
from table1, table2
where table1.id = table2.id
and ( table1.name <> table2.name or
table1.class <> table2.class or table1.status <> table2.status)
and (table1.status <>'LEFT' and table2.status <>'LEFT')

Count number of rows between start and end date

I have a table with few hundred thousand rows, with columns containing a start and finish datetime, something like this:
ID StartDateTime FinishDateTime
--------------------------------------------------------
1 2001-01-01 04:05:06.789 2001-02-03 04:05:06.789
2 2001-01-01 05:05:06.789 2001-01-01 07:05:06.789
3 2001-01-01 06:05:06.789 2001-02-04 07:05:06.789
4 2001-03-01 06:05:06.789 2001-02-03 04:05:06.789
For each row, I need to count the number of 'active' rows at the start time; as in count rows that start before and finish after the startdatetime for each row. For instance: for ID=3, the startdatetime falls between the startdatetime and finishdatetime of ID=1 and ID=2, but not ID=3 or ID=4, so it should return 2.
The desired output is:
ID ActiveRows
-----------------
1 0
2 1
3 2
4 0
I can get it to work using the query below, but it takes hours to run.
select
ID,
(select count(1)
from table tbl2
where tbl2.StartDateTime < tbl.StartDateTime
and tbl2.FinishDateTime > tbl.StartDateTime) as 'ActiveRows'
from
table tbl
I've also tried joining the table on itself, but it also seems extremely slow.
select
tbl.ID, count(1)
from
table tbl
left join table
tbl2 on tbl2.StartDateTime < tbl.StartDateTime
and tbl2.FinishDateTime > tbl.StartDateTime
group by
tbl.ID
What is the fastest way to perform this calculation?
You can do this using Apply operator
SELECT tbl.id,
oa.activerows
FROM yourtable tbl
OUTER apply(SELECT Count(tbl2.id)
FROM yourtable tbl2
WHERE tbl2.startdatetime < tbl.startdatetime
AND tbl2.finishdatetime > tbl.startdatetime) oa (activerows)
and your original query should be using LEFT JOIN to get the ID's with 0 count
To further improve the performance you can create a non clustered index on yourtable
Create Nonclustered Index Nix_table on
yourtable (startdatetime,finishdatetime) Include (Id)
Live Demo

Resources