I am very new the DB scripting, but I have the following Select statements returning 3 different Data sets from 2 separate tables.
SELECT
A.CustomerId,
C.Customername
FROM
BankCustomer C
RIGHT JOIN
BankAssociation A
ON C.CustomerId = A.CustomerId
SELECT
A.TypeId,
T.Type
FROM
BankAssociation A
LEFT JOIN
BankTypes T
On A.TypeId = T.TypeId
SELECT
A.CustomerId2,
C.Customername
FROM
BankCustomer C
RIGHT JOIN
BankAssociation A
On C.CustomerId = A.CustomerId2
The multiple SELECTstatements will return DATA in separate tables as such:
SELECT 1
Damian Wayne
Peter Parker
SELECT 2
CLEANS
BUILDS
SELECT 3
Bruce Wayne
Ben Parker
My question:
I want to concatenate the Rows with a verb that will display the Rows something like this
Damian Wayne CLEANS for Bruce Wayne
Peter Parker BUILDS for Ben Parker
You can try this.
SELECT CONCAT(C.CustomerName , ' ' , T.Type , ' for ' , C2.CustomerName ) FROM
BankAssociation A
LEFT JOIN BankCustomer C ON C.CustomerId = A.CustomerId
LEFT JOIN BankCustomer C2 ON C2.CustomerId = A.CustomerId2
LEFT JOIN BankTypes T On A.TypeId = T.TypeId
Related
I have the following tables:
Customers
ID Name
============
1 John
2 Alice
3 Bob
Orders
ID CustomerID Status
==========================
1001 1 1
1002 2 1
1003 2 2
1004 3 2
I'd like to join tables showing one entry per customer only (the one with lowest Status) i.e.
ID Name OrderID
======================
1 John 1001
2 Alice 1002
3 Bob 1004
Thanks to the answer to this question, I chose 2 solutions which produce the same output:
Solution 1
SELECT c.id, c.name, o.id FROM customers AS c
INNER JOIN orders AS o ON
c.id = o.customerid
WHERE o.status = (SELECT MIN(status) FROM orders WHERE customerid = c.id)
Solution 2
SELECT c.id, c.name, o.id FROM customers as c
INNER JOIN orders AS o ON
o.id = (SELECT TOP 1 id FROM orders WHERE customerid = c.id ORDER BY status)
Trying to understand which one runs faster, I used SQL Fiddle View Execution Plan which gave the following:
Solution 1
Solution 2
How to interpret those diagrams and which one performs faster?
Using MS SQL Server 2016.
Here's my breakdown and the last one is my suggestion to you.
Query Cost 67%
SELECT c.id, c.name, o.id FROM #Customers AS c
INNER JOIN #Orders AS o ON
c.id = o.customerid
WHERE o.status = (SELECT MIN(status) FROM #Orders WHERE customerid = c.id)
Query Cost 66%
SELECT c.id, c.name, o.id FROM #Customers as c
INNER JOIN #Orders AS o ON
o.id = (SELECT TOP 1 id FROM #Orders WHERE customerid = c.id ORDER BY status)
Query Cost 47%
SELECT
x.CustID,
x.Name,
x.OrderID
FROM (SELECT
C.id CustID,
c.Name,
o.ID OrderID,
o.status,
ROW_NUMBER() OVER (PARTITION BY c.id ORDER BY o.status) rn
FROM #Customers c
INNER JOIN #Orders o
ON o.CustomerID = c.ID) x
WHERE x.rn = 1
I work with the AventureWorks2014 database in Microsoft SQL Server. I need to create a view that will show the CustomerID, the full name and the TOTAL amount sold to client through the web.
My problem is that I can't seem to get the values corresponding to a single customer add up so that a single customer answers to a single line in my result. This is the code I have, any help would be appreciated. I basically need to show the total amount sold to clients on the web.
if object_id('vTotalWebSalesPerCustomer', 'v') is not null
drop view vTotalWebSalesPerCustomer;
go
create view vTotalWebSalesPerCustomer
as
select distinct
c.CustomerID,
ltrim(rtrim(concat(concat(concat(concat(concat(concat(concat(p.Title, ' '), p.LastName), ', '), ' '), p.FirstName), ' '), p.Suffix))) as NomClient,
soh.TotalDue
from
[Sales].[Customer] as c
left join
[Person].[Person] as p on c.CustomerID = p.BusinessEntityID
left join
[Sales].[SalesOrderHeader] as soh on soh.CustomerID = c.CustomerID
where
year(soh.OrderDate) = 2014
and datepart(quarter, soh.OrderDate) = 1
and [OnlineOrderFlag] = 1
go
select *
from vTotalWebSalesPerCustomer
Thanks
Sounds like you need to use GROUP BY and SUM(), example:
SELECT column-names
FROM table-name
WHERE condition
GROUP BY column-names
ORDER BY column-names
Such as:
SELECT SUM(O.TotalPrice), C.FirstName, C.LastName
FROM [Order] O JOIN Customer C
ON O.CustomerId = C.Id
GROUP BY C.FirstName, C.LastName
ORDER BY SUM(O.TotalPrice) DESC
Would return:
Sum FirstName LastName
117483.39 Horst Kloss
115673.39 Jose Pavarotti
113236.68 Roland Mendel
57317.39 Patricia McKenna
52245.90 Paula Wilson
34101.15 Mario Pontes
32555.55 Maria Larsson
DISTINCT filters result rows to remove duplicates. What I think you want is to aggregate rows. Perhaps this will do what you want:
create view vTotalWebSalesPerCustomer as
select c.CustomerID,
ltrim(rtrim(concat(concat(concat(concat(concat(concat(concat(p.Title, ' '), p.LastName), ', '), ' '), p.FirstName), ' '), p.Suffix))) as NomClient,
sum(soh.TotalDue) as TotalDue
from [Sales].[Customer] as c
left join [Person].[Person] as p on c.CustomerID = p.BusinessEntityID
left join [Sales].[SalesOrderHeader] as soh on soh.CustomerID = c.CustomerID
where year(soh.OrderDate) = 2014 and datepart(quarter, soh.OrderDate)=1 and [OnlineOrderFlag] = 1
group by c.CustomerID,NomClient
Note that I removed distinct, added sum operator on the amount you want to total, and group by the customer id and name fields (SQL Server requires that you list in the GROUP BY all result columns which are not being aggregated).
You can use the following VIEW using a GROUP BY on the SELECT:
IF OBJECT_ID('vTotalWebSalesPerCustomer', 'v') IS NOT NULL
DROP VIEW vTotalWebSalesPerCustomer;
GO
CREATE VIEW vTotalWebSalesPerCustomer AS
SELECT
x.CustomerID,
LTRIM(RTRIM(CONCAT(p.Title, ' ', p.LastName, ', ', p.FirstName, ' ', p.Suffix))) AS NomClient,
x.TotalDue
FROM (
SELECT
c.CustomerID AS CustomerID,
SUM(soh.TotalDue) AS TotalDue
FROM [Sales].[Customer] AS c
LEFT JOIN [Sales].[SalesOrderHeader] AS soh ON soh.CustomerID = c.CustomerID
WHERE YEAR(soh.OrderDate) = 2014 AND DATEPART(quarter, soh.OrderDate) = 1 AND [OnlineOrderFlag] = 1
GROUP BY c.CustomerID
)x LEFT JOIN [Person].[Person] AS p ON x.CustomerID = p.BusinessEntityID
GO
Note: You only need one CONCAT function to concat all string values.
I have the following relationship: Bank -> Financing -> Contracts -> Supplier
I have to select all the Banks that is related to a Supplier, using the query below:
SELECT DISTINCT A.Name AS BankName, A2.Name as SupplierName
FROM Companies A
INNER JOIN Financing F ON F.IdFinancialCompany = A.Id
INNER JOIN Contracts C ON F.IdContract = C.Id
INNER JOIN Companies A2 ON C.IdSupplier = A2.Id
GROUP BY A.Name, A2.Name
So far, so good.
Now I have to list the number of contracts that are active and the number of total contracts, so I thought about including a subquery:
SELECT DISTINCT A.Name AS BankName, A2.Name as SupplierName,
(SELECT COUNT(C.Id)),
(SELECT COUNT(C.Id) WHERE C.ContractStatus = 1)
FROM Companies A
INNER JOIN Financing F ON F.IdFinancialCompany = A.Id
INNER JOIN Contracts C ON F.IdContract = C.Id
INNER JOIN Companies A2 ON C.IdSupplier = A2.Id
GROUP BY A.Name, A2.Name
Line 2 Works well, but I got na error in line 3:
Column 'Contracts.ContractStatus' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
I expect the following result:
BANK NAME | SUPPLIER NAME | TOTAL CONTRACTS | ACTIVE CONTRACTS
Bank 1 | Supplier 1| 5 | 2
How can I achieve this? I'm using SQL Server 2014
Thanks in advance!
Remove the distinct since your group by and use CASE
SELECT A.Name AS BankName, A2.Name as SupplierName,
COUNT(C.Id),
SUM(CASE WHEN C.ContractStatus = 1 THEN 1 ELSE 0 END)
FROM Companies A
INNER JOIN Financing F ON F.IdFinancialCompany = A.Id
INNER JOIN Contracts C ON F.IdContract = C.Id
INNER JOIN Companies A2 ON C.IdSupplier = A2.Id
GROUP BY A.Name, A2.Name
I need to show in a temporary table one user a many phone of that user, but I'm stuck
in the select, I need something like this:
user1 phone1 phone2 phone3 phone4 phone5
11816116-5 8555588 77877888 33254477 224474 45777885
this is the code that I'm trying:
select
phone As phonenum
Into #Tmp_phonenumber
From
clients_has_phones
where
user_number='11816116-5'
thanks in advance.
I can not think of a good way of doing the select statement other than by self joining on how ever many phone numbers your user may have.. With that being said you can try this for your select statement:
;With CTE_Main as (
Select
id
,Fono
,row_number()
Over(Partition by ID order by Fono) as RN
From sucursales
), CTE_Users as (
Select
id as id_num
from sucursales
group by id
)
Select
id_num
,a.Fono as Phone_1
,b.Fono as Phone_2
,c.Fono as Phone_3
,d.Fono as Phone_4
,e.Fono as Phone_5
From CTE_Users as realz
Left Join [CTE_Main] as a on a.id = realz.id_num and a.RN = 1
Left Join [CTE_Main] as b on b.id = realz.id_num and b.RN = 2
Left Join [CTE_Main] as c on c.id = realz.id_num and c.RN = 3
Left Join [CTE_Main] as d on d.id = realz.id_num and d.RN = 4
Left Join [CTE_Main] as e on e.id = realz.id_num and e.RN = 5
I know its kind of lengthy but it will display the results in the way that you want them.. My example only uses 5 rows but it should be pretty self explanatory.
Sql Fiddle: http://sqlfiddle.com/#!3/496f6/1
i have a table like this
ID Name Mother Father
1 Sue NULL NULL
2 Ed NULL NULL
3 Emma 1 2
4 Jack 1 2
5 Jane NULL NULL
6 Bonnie 5 4
7 Bill 5 4
and i need output as below
ID Name Mother Father
3 Emma sue ed
4 jack sue ed
6 bonnie jane jack
7 bill jane jack
i have tried writing query with join n cte but couldnt come up with the logic , can someone please help me out
SELECT t.ID, t.Name, m.Name, f.Name
FROM your_table t
INNER JOIN your_table m ON m.ID = t.Mother
INNER JOIN your_table f ON f.ID = t.Father
Use LEFT JOIN if you want to include records without Mother and/or Father nodes:
SELECT t.ID, t.Name, ISNULL(m.Name, 'Orphan') Mother, ISNULL(f.Name, 'Orphan') Father
FROM your_table t
LEFT JOIN your_table m ON m.ID = t.Mother
LEFT JOIN your_table f ON f.ID = t.Father
try something like this:
select
p.id, p.name, p1.name as mother, p2.name as father
from people p
inner join people p1 on p1.id = p.mother
inner join people p2 on p2.id = p.father
Select Query
SELECT A.*
FROM tbl A
,tbl M
,tbl F
WHERE A.Mother = M.ID
AND A.Father = F.ID
without inner join..