SQL - Updating rows in one table with values from another table - Multiple match - sql

I am trying to append values in my Customer table with data from my Sales table.
The customer can have multiple records in the sales table:
Hereby a joined view:
SalesID CustomerID SalesComment CustomerComment
------------------------------------------------------------
1 14 Com1 Customer Comment 1
2 15 Com2 Customer Comment 2
3 14 Com3 Customer Comment 1
4 14 Customer Comment 1
I want to make an update like this:
UPDATE Customer
SET Customer.ShopBookKommentar = CAST([ShopBookKommentar] AS NVARCHAR(MAX)) +
CAST(CHAR(13) + CHAR(10) + S.Comments AS NVARCHAR(MAX))
FROM Customer C
INNER JOIN Sales S ON S.CustomerID = c.ID
But it's not updating any of the Customer rows where one of the Sales rows comment field is empty ('')

It looks like you are using SQL Server. You need to use the table alias for the update:
UPDATE c
SET ShopBookKommentar = c.ShopBookKommentar + CHAR(13) + CHAR(10) + S.Comments
FROM Costumer C INNER JOIN
Sales S
ON S.CostumerID = c.ID;
You only need the cast() if for some reason the intermediate result isn't big enough. But that shouldn't be a problem.
EDIT:
I am guessing that you actually want to apply multiple comments from different rows of Sales. That is a bit trickier:
UPDATE c
SET ShopBookKommentar = c.ShopBookKommentar + c.somm
FROM (SELECT c.*,
(SELECT CHAR(13) + CHAR(10) + S.Comments
FROM Sales s
WHERE S.CostumerID = c.ID AND
S.Comments IS NOT NULL
FOR XML PATH, TYPE
).value(N'.[1]', N'varchar(max)') as scomm
FROM c
) Costumer C INNER JOIN
(Sales S
ON ;

Related

How can i output table data (multiple rows) as a multiple rows of concatenated strings

I am trying to take table data built from a select statement using 2 tables and a group by ... and then output each row of data into a single row concatenated text.
I have tinkered with trying to DECLARE, SET and print as concat string.
use ap;
SELECT v.vendorid as 'VendorID', count(i.invoiceid) as 'Invoice Count',
sum(i.invoicetotal) as 'Invoice Total'
FROM vendors v
JOIN invoices i on i.vendorid = v.vendorid
GROUP BY v.vendorid
trying to output it like...
VendorID = 34 Invoice Count 2 Invoice Totals = 1,200.12
Just concatenate it into a string. You just need to cast your numeric values to VARCHARs.
select 'VendorID = ' + CAST(v.vendorid AS VARCHAR(10)) + ' Count ' + CAST(count(i.invoiceid) AS VARCHAR(10)) +
' Invoice Totals = ' + FORMAT(sum(i.invoicetotal), 'c2')
from vendors v JOIN invoices i on i.vendorid = v.vendorid
group by v.vendorid
With this sample data:
create table vendors (vendorid int)
create table invoices (vendorid int, invoiceid int, invoicetotal money)
insert into vendors values (34)
insert into invoices values (34, 1, 1000), (34, 2, 200.12)
Returns:
VendorID = 34 Count 2 Invoice Totals = $1,200.12

dynamic pivot sql

I am trying to select data from a customers table, a contract spend table, and a contract name table. My tables look something like this
Customers
CustomerID CustomerName Address etc
1 "ABC Corp" "123 Here Ave"
2 "Acme Corp" "101 Lets Ave"
ContractTypes
ContractTypeID ContractName
1 "Website Hosting"
2 "Domain Hosting"
3 "Email Hosting"
ServiceSpend
ServiceSpendID ContractTypeID CustomerID Spend
1 2 1 5.99
2 1 1 5.99
3 1 2 9.99
I would like to produce the following table
CustomerID CustomerName Address DomainHosting WebsiteHosting
1 "ABC Corp" "123 Here Ave" 9.99 5.99
Currently I have the following sql statement which works but I need to be able to define the columns dynamically as we need to be able to add additional contract names to the database and still report on the customer spend
select *
from
(
SELECT
Customers.CustomerID, Customers.ContactName, Customers.Address, ContractTypes.ContractName AS ContractName, ServiceSpend.Spend
FROM
Customers INNER JOIN
ServiceSpend ON Customers.CustomerID = ServiceSpend.CustomerID
INNER JOIN
ContractTypes ON ServiceSpend.ContractTypeID = ContractTypes.ContractTypeID
) src
pivot
(
sum(spend)
for ContractName in ([Website Hosting],[Domain Hosting])) piv;
Does anyone know how I might add my columns dynamically
You have to use dynamic sql to construct the columns for your output:
DECLARE #Columns VARCHAR(1000) = STUFF((
SELECT ',[' + ContactName + ']'
FROM ContactTypes
FOR XML PATH('')
),1,1,'')
DECLARE #Sql VARCHAR(1000) = '
SELECT *
FROM (
SELECT
Customers.CustomerID,
Customers.ContactName,
Customers.Address,
ContractTypes.ContractName,
ServiceSpend.Spend
FROM Customers
INNER JOIN ServiceSpend
ON Customers.CustomerID = ServiceSpend.CustomerID
INNER JOIN ContractTypes
ON ServiceSpend.ContractTypeID = ContractTypes.ContractTypeID
) SRC
PIVOT (SUM(Spend) FOR ContractName IN (' + #Columns + ')) piv;'
EXEC (#Sql)

How can I select bottom row from second table using inner join in SQL Server 2000?

How can I select bottom row from second table using inner join from two tables?
Here [customer records] contains customer details and photoinfo contains photodetails.
SELECT
CR.customernumber, CR.customername,
CR.Addressline1, CR.city, CR.state,
CR.pincode, CR.landline, CR.mobile,
CR.dob, CR.gender,
PR.FileName, CR.remarks, CR.fulladdress, CR.regno,
CR.qualification, CR.bg, CR.fname,
CR.field1, CR.field2, CR.field3, CR.field4, CR.field5,
CR.sign
from
[customer records] CR
inner join
photoinfo PR on PR.customernumber = CR.customernumber
where
CR.customernumber >= 5050 and CR.customernumber <= 5100
order by
CR.customernumber
Here filename is text field from photoinfo. i need to select every last row of filename from photoinfo
Thanks in advance
Customer records
cnumber cname Mobile Gender
2000 K.Deepalakshmi F
2001 J.Geetha 9789426497 F
photoinfo
cid cnumber Filename
5152 2000 B6216.jpg
5153 2001 B6203.jpg
5154 2001 B6209.jpg
5155 2001 B6205.jpg
here i want join the above two tables based on cnumber(customernumber). and i want join last or the first filename from photoinfo based on cid like.
expected output
cnumber cname filename Mobile Gender
2000 K.Deepalakshmi B6216.jpg F
2001 J.Geetha B6205.jpg 9789426497 F
Create & insert Customer table
create table #customer(cnumber decimal(18,0),cname varchar(100),Mobile varchar(100),Gender varchar(1))
insert into #customer values
(2000,'K.Deepalakshmi','','F'),
(2001,'J.Geetha','9789426497','F')
Create & Insert Photo info table
create table #photoinfo(cid decimal(18,0),cnumber decimal(18,0),filename varchar(100))
insert into #photoinfo values
(5152,2000,'B6216.jpg'),
(5153,2001,'B6203.jpg'),
(5154,2001,'B6209.jpg'),
(5155,2001,'B6205.jpg')
Result
select c.cnumber,c.cname,p.filename,c.Mobile,c.Gender
from #customer c
join #photoinfo p on p.cnumber=c.cnumber
join (select c.cnumber,max(p.cid) cid
from #customer c
join #photoinfo p on p.cnumber=c.cnumber
group by c.cnumber) r on r.cnumber=p.cnumber and p.cid=r.cid

trying to concatenate a column into a comma delimited list

i have 3 tables, 1 for products and one for categories the products are assigned to. what IM trying to do is concatenate the column called stCategoryName to a single column in a comma delimited list.
Basically I have the products table containing the primary key for each product and im trying to figure out how to concatenate all the stcategoryName column next to each product so i can have a simplified return
what im trying to get is the following.
stProductID stCategoryName
123 category1,category2,category3
SELECT
dbo.StoreItemTracking.StCategoryID,
dbo.StoreItemTracking.StProductID,
dbo.StoreItemTracking.viewOrder,
dbo.StoreCategories.StCategoryName,
dbo.Store_Products.PartNumber
FROM
dbo.StoreItemTracking
INNER JOIN dbo.StoreCategories
ON dbo.StoreItemTracking.StCategoryID = dbo.StoreCategories.StCategoryID
INNER JOIN dbo.Store_Products
ON dbo.StoreItemTracking.StProductID = dbo.Store_Products.ID
Im stuck as to how to concatenate a column where the query contains 3 tables to select from.
any help greatly appreciated
Look at using coalesce to turn category into a CSV:
See example:
DECLARE #EmployeeList varchar(100)
SELECT #EmployeeList = COALESCE(#EmployeeList + ', ', '')
+ CAST(Emp_UniqueID AS varchar(5))
FROM SalesCallsEmployees
WHERE SalCal_UniqueID = 1
SELECT #EmployeeList
You can also use CTE's or Subqueries. See:
http://archive.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=createacommadelimitedlist
Another nice and easy example:
http://www.codeproject.com/Articles/21082/Concatenate-Field-Values-in-One-String-Using-CTE-i
This:
FId FName
--- ----
2 A
4 B
5 C
6 D
8 E
with:
;WITH ABC (FId, FName) AS
(
SELECT 1, CAST('' AS VARCHAR(8000))
UNION ALL
SELECT B.FId + 1, B.FName + A.FName + ', '
FROM (And the above query will return
SELECT Row_Number() OVER (ORDER BY FId) AS RN, FName FROM tblTest) A
INNER JOIN ABC B ON A.RN = B.FId
)
SELECT TOP 1 FName FROM ABC ORDER BY FId DESC
becomes:
FName
----------------------------
A, B, C, D, E,
Don't understand how your products and categories are connected but in general I do like this to create comma separated lists.
SELECT table1.Id
,Csv
FROM table1
CROSS APPLY (
-- Double select so we can have an alias for the csv column
SELECT (SELECT ',' + table2.Name
FROM table2
WHERE table2.Id = table1.Id
FOR XML PATH('')
) AS RawCsv
) AS CA1
CROSS APPLY (
-- Trim the first comma
SELECT RIGHT(RawCsv, LEN(RawCsv) - 1) AS Csv
) AS CA2

SQL Server: pair of IDs which has the same elements on the same table

I'm working with SQL Server 2005.
I have a table INVENTORY with columns ProductId, BranchId, Stock
I want to select the pairs of BranchId which have the exactly the same products.
For example
BranchId - ProductId
1 - a
1 - b
1 - c
2 - b
2 - c
3 - a
3 - b
3 - c
Must return the tuple
Inventory1.BranchId - Inventory2.BranchId
1 - 3
3 - 1
Does not mater if a pair is duplicated in two tuples (1-3 and 3-1).
The idea is:
SELECT I1.BranchId,I1.ProductId,I2,BranchId,I2.ProductId
FROM inventory AS I1,inventory as I2
WHERE I1.BranchId<>I2.BranchId AND
"I1.ProductId's Exists in the products list of I2" //This is the part I don't know how to do
Any idea?
Thanks
You can perform this by using CTEs. The main idea is to concatenate the list of products for each branch and then to join this CTE with itself:
WITH InventoryCTE
AS
(
SELECT
I1.BranchId
, STUFF(
(SELECT
', ' + I2.ProductId
FROM Inventory I2
WHERE I1.BranchId = I2.BranchId
ORDER BY I2.ProductId
FOR XML PATH(''), TYPE
).value('.','varchar(max)')
,1,2, ''
) AS ProductIds
FROM Inventory I1
GROUP BY I1.BranchId
)
SELECT I1.BranchId, I2.BranchId, I2.ProductIds
FROM
InventoryCTE I1
INNER JOIN InventoryCTE I2 ON I2.ProductIds = I1.ProductIds
WHERE I1.BranchId != I2.BranchId