SQL Moving SUBSTRING select into INNER JOIN - sql

I have this query
SELECT ID,
SUBSTRING(( SELECT DISTINCT ',' + CONVERT(varchar(10), CC.CompanyId)
FROM Company CC
INNER JOIN CompanyProducts NP2
ON CC.CompanyId = NP2.CompanyId
WHERE NP.CompanyProducts Id = NP2.PrimaryCompanyProducts Id
AND NP2.CompanyProducts Id <> NP2.CompanyProducts Id
FOR XML PATH('')),2,200000) AS CompanyIdList
FROM CompanyProducts NP
I would like to add the SELECT into an INNER JOIN which I will add to my select to check if the return is null or zero
it will be something like this
SELECT ID,
SUBSTRING(( SELECT DISTINCT ',' + CONVERT(varchar(10), CC.CompanyId)
FROM Company CC
INNER JOIN CompanyProducts NP2
ON CC.CompanyId = NP2.CompanyId
WHERE NP.CompanyProducts Id = NP2.PrimaryCompanyProducts Id
AND NP2.CompanyProducts Id <> NP2.CompanyProducts Id
FOR XML PATH('')),2,200000) AS CompanyIdList,
CompanyIdCount --this will be null or a real value
FROM cmp.CompanyProducts NP
INNER JOIN(SELECT DISTINCT A.CompanyProductsId,
(SELECT DISTINCT ',' + CONVERT(varchar(10), CC.CompanyId)
FROM Company CC
INNER JOIN CompanyProducts NP2
ON CC.CompanyId = NP2.CompanyId
WHERE NP.CompanyProducts Id = NP2.PrimaryCompanyProducts Id
AND NP2.CompanyProducts Id <> NP2.CompanyProducts Id ) AS CompanyIdCount
FROM cmp.CompanyProducts A
)E ON NP.CompanyNotificationId = E.CompanyNotificationId
How can I get the inner JOIN to incident null for no records or 1 record or more? THanks

Related

Update a column separated by comma for multiple values?

I have following table Userinfo_attarea:
id employee_id area_id
182521 4391 2
182522 4391 3
Personnel_area:
id areaid
1 Area Name
2 PROJECT80
3 PROJECT69
When i update it works fine foe single value but i need a column with multiple values separeted by comma as mentioned below
Expected Output:
areaname
PROJECT80,PROJECT69
i am using following query for update
UPDATE employee
SET employee.areaname = p.areaname
FROM employee join userinfo u
on u.badgenumber=employee.emp_reader_id join userinfo_attarea ua on ua.employee_id=u.userid join personnel_area p on ua.area_id=p.id
JOIN inserted I ON u.userid= I.employee_id
Thanks in advance...
You can try this :
Update E set areaname = T.areaname from #Employee E
Inner Join
(
Select employee_id,STUFF((SELECT ', ' + CAST(areaid AS VARCHAR(10)) [text()]
FROM (
Select U.employee_id,P.areaid from #Userinfo_attarea U
Inner Join #Personnel_area P on U.area_id = P.id
) B
WHERE employee_id = A.employee_id
FOR XML PATH(''), TYPE)
.value('.','NVARCHAR(MAX)'),1,2,' ') areaname from
(
Select U.employee_id,P.areaid from #Userinfo_attarea U
Inner Join #Personnel_area P on U.area_id = P.id
) A
GROUP BY employee_id
) T on T.employee_id = E.id
Working demo

Convert a column of Rows to only one column column in SQL Server query

I have this query in SQL Server 2012 :
select
tblplantitle.id, tblplantoproductpayment.productid
from
tblplantitle
inner join
tblplan on tblplan.plantitleid = tblplantitle.id
inner join
tblplantoproductpayment on tblplantoproductpayment.planid = tblplan.id
group by
tblplantitle.id, tblplantoproductpayment.productid
The result is like this :
id productid
1 1
1 2
1 3
1 10
2 5
2 1
3 4
3 11
but I want this result :
1 1,2,3,10
2 5,1
3 4,11
How can I get that result ?
Try this:
WITH cte as
(
select
tblplantitle.id, tblplantoproductpayment.productid
from
tblplantitle
inner join
tblplan on tblplan.plantitleid = tblplantitle.id
inner join
tblplantoproductpayment on tblplantoproductpayment.planid = tblplan.id
group by
tblplantitle.id, tblplantoproductpayment.productid
)
SELECT id, productid =
STUFF((SELECT ', ' + productid
FROM cte b
WHERE b.id= a.id
FOR XML PATH('')), 1, 2, '')
FROM cte a
GROUP BY id
Use the below query for the desired output.
SELECT tblplantitle.id
, STUFF((SELECT ', ' + CAST(tblplantoproductpayment.productid AS VARCHAR(10)) [text()]
FROM tblplantoproductpayment
WHERE tblplantoproductpayment.planid = tblplan.id
FOR XML PATH(''), TYPE).value('.','NVARCHAR(MAX)'),1,2,' ') List_ProductIds
FROM tblplantitle
INNER JOIN tblplan on tblplan.plantitleid = tblplantitle.id
GROUP BY tblplantitle.id

Trying to join two sql statement

I would like to join Query 1 and Query 2 on TripId.
Query 1
SELECT tblTrips.TripId,tblVehicles.VehicleNo
FROM tblTrips INNER JOIN tblVehicles ON tblTrips.VehicleId = tblVehicles.VehicleId
Query 2
;with T1 as (
SELECT tblTrips.TripId, tblTripDeductions.Amount, CONVERT(VARCHAR(400),tblDeductionTypes.DeductionType+' - '+tblTripDeductions.Description+' - '+ CONVERT(VARCHAR(24),tblTripDeductions.Amount)) as DeductionFor
FROM tblTrips INNER JOIN
tblTripDeductions ON tblTrips.TripId = tblTripDeductions.TripId INNER JOIN
tblDeductionTypes ON tblTripDeductions.DeductionId = tblDeductionTypes.DeductionId
)select **T1.TripId**, SUM(T1.Amount) as Amount, stuff((select '#',' ' + CONVERT(varchar(1000),T2.DeductionFor) from T1 AS T2 where T1.TripId = T2.TripId for xml path('')),1,1,'') [Description] from T1
Group by TripId
First query's output is list of TripId and VehicleNo.
Second query's output is list of TripId, Amount and description.
And my desire output is TripId, VehicleNo, amount and description.
The Syntax for WITH (Common Table Expressions) allows you to create multiple CTE's.
Using that you can turn your final part of Query2 in to a CTE (Which I'll name Query2) and your query for Query1 can also be made in to a CTE (which I'll name Query1).
Then, the final SELECT statement can simply join those two CTE's together.
;
WITH
T1 as (
SELECT tblTrips.TripId, tblTripDeductions.Amount, CONVERT(VARCHAR(400),tblDeductionTypes.DeductionType+' - '+tblTripDeductions.Description+' - '+ CONVERT(VARCHAR(24),tblTripDeductions.Amount)) as DeductionFor
FROM tblTrips INNER JOIN
tblTripDeductions ON tblTrips.TripId = tblTripDeductions.TripId INNER JOIN
tblDeductionTypes ON tblTripDeductions.DeductionId = tblDeductionTypes.DeductionId
)
,
Query2 AS (
select **T1.TripId**, SUM(T1.Amount) as Amount, stuff((select '#',' ' + CONVERT(varchar(1000),T2.DeductionFor) from T1 AS T2 where T1.TripId = T2.TripId for xml path('')),1,1,'') [Description] from T1
Group by TripId
)
,
Query1 AS (
<Your Code For Query1>
)
SELECT
*
FROM
Query1
INNER JOIN
Query2
ON Query1.TripID = Query2.TripID
I haven't don't anything to check your queries, as the layout that you have used isn't very readable.
Just merge the queries using CTE (didn't change/review your code, just formatted it for the sake of readability - input was pretty horrible to read)
;WITH T1 AS (
SELECT tblTrips.TripId
, tblTrips.DestinationDistrictId
, tblTrips.VehicleId
, tblTrips.No
, tblVehicles.VehicleNo
, tblTrips.CoachNo
, CONVERT(VARCHAR(24), tblTrips.GoDate, 105) AS GoDate
, tblTrips.GoTime
, CASE WHEN tblTrips.IsCome=1
THEN CONVERT(VARCHAR(24), tblTrips.ComeDate, 105)
ELSE '-'
END AS ComeDate
, CASE WHEN tblTrips.IsCome=1
THEN tblTrips.ComeTime
ELSE '-'
END AS ComeTime
, CASE WHEN tblTrips.IsCome=1
THEN (SD.DistrictName + ' - ' + DD.DistrictName + ' - ' + SD.DistrictName)
ELSE (SD.DistrictName + ' - ' + DD.DistrictName)
END AS Destination
, tblSupervisors.Name AS Supervisor
, tblDrivers.Name AS Driver
, tblTrips.AdvanceAmount
, tblTrips.AdvanceDescription
FROM tblTrips
INNER JOIN tblSupervisors ON tblTrips.SuperVisorId = tblSupervisors.SupervisorId
INNER JOIN tblDrivers ON tblTrips.DriverId = tblDrivers.DriverId
INNER JOIN tblDistricts SD ON tblTrips.StartDistrictId = SD.DistrictId
INNER JOIN tblDistricts DD ON tblTrips.DestinationDistrictId = DD.DistrictId
INNER JOIN tblVehicles ON tblTrips.VehicleId = tblVehicles.VehicleId
)
, Q1 AS (
SELECT T1.TripId
, SUM(T1.Amount) AS Amount
, STUFF((
SELECT '#', ' ' + CONVERT(VARCHAR(MAX), T2.DeductionFor)
FROM T1 AS T2
WHERE T1.TripId = T2.TripId FOR XML PATH(''))
,1,1,'') AS [Description]
FROM T1
GROUP BY TripId
)
, Q2 AS (
SELECT tblTrips.TripId
, tblTripDeductions.Amount
, CONVERT(VARCHAR(400), tblDeductionTypes.DeductionType + ' - ' + tblTripDeductions.Description + ' - ' + CONVERT(VARCHAR(24), tblTripDeductions.Amount)) AS DeductionFor
FROM tblTrips
INNER JOIN tblTripDeductions ON tblTrips.TripId = tblTripDeductions.TripId
INNER JOIN tblDeductionTypes ON tblTripDeductions.DeductionId = tblDeductionTypes.DeductionId
)
SELECT *
FROM Q1
INNER JOIN Q2 ON Q1.TripId = Q2.TripId

Single Line separated records in SQL SERVER Query result

I had a query that returned multiple rows from a table. Then I converted that query to this one:
;with mycte as
(select s.FirstName + ' ' + s.LastName as Name from ClientStaff cs
left outer join Staff s on s.Id = cs.StaffId
left outer join GeneralStatus gs on gs.Id = s.StatusId
where cs.ClientId = #clientId and gs.Name = 'Active')
select #staff = (select distinct staff = REPLACE(REPLACE(REPLACE((select Name AS [data()] FROM mycte a
order by a.Name for xml path),'</row><row>',', '),'</row>',''),'<row>','') from mycte b)
It returns those rows in a single comma-separated row.
Now I don't want comma-separated values, instead I want single-line-separated values.
Can anyone tell me if it is possible or not?
Thanks in advance.
declare #staff varchar(max)
;with mycte as
(
select distinct s.FirstName + ' ' + s.LastName as Name
from ClientStaff cs
left outer join Staff s on
s.Id = cs.StaffId
left outer join GeneralStatus gs on
gs.Id = s.StatusId
where cs.ClientId = #clientId and gs.Name = 'Active'
)
select #staff = isnull(#staff + char(13), '') + Name
from mycte b
print #staff

How can I use Sql to Order By This Statement?

How can I order the list 'widgets_spec by number of widgets?
select distinct
m.p_c_id
,(select distinct '<li>' +convert(varchar,widgets) + '<br> '
from dbo.spec_master m2
where m.p_c_id = m2.p_c_id and widgets is not null
for xml path(''), type).value('.[1]', 'nvarchar(max)'
) as widgets_spec
from dbo.spec_master m
inner join dbo.ProductVaration pv on pv.p_c_id = m.p_c_id
inner join dbo.Varation v on v.varation_id = pv.varation_type_id
where v.varation_id = 4
group by m.p_c_id
Right now output looks like:
<li>10<br> <li>12<br> <li>15<br> <li>8<br>
When I want it to look like:
<li>8<br> <li>10<br> <li>12<br> <li>15<br>
Thanks for your help.
EDIT: I'm trying to order the internal select statement that concatenates the values.
You do not need both Distinct and Group By. You should use one or the other. In this case, I believe you have to use Group By for it to work.
Select m.p_c_id
, (
Select '<li>' + Cast( m2.num_of_lights As varchar(10)) + '<br /> '
From dbo.spec_master As m2
Where m.p_c_id = m2.p_c_id
And m2.num_of_lights Is Not Null
Group By m2.num_of_lights
Order By m2.num_of_lights
For Xml Path(''), type).value('.[1]', 'nvarchar(max)'
) As numLights_spec
From dbo.spec_master As m
Inner Join dbo.ProductVaration As pv
On pv.p_c_id = m.p_c_id
Inner Join dbo.Varation As v
On v.varation_id = pv.varation_type_id
Where v.varation_id = 4
Group by m.p_c_id
select distinct
m.p_c_id
,(select distinct '<li>' +convert(varchar,num_of_lights) + '<br> '
from dbo.spec_master m2
where m.p_c_id = m2.p_c_id and num_of_lights is not null
ORDER BY convert(varchar,num_of_lights)
) as numLights_spec
from dbo.spec_master m
inner join dbo.ProductVaration pv on pv.p_c_id = m.p_c_id
inner join dbo.Varation v on v.varation_id = pv.varation_type_id
where v.varation_id = 4
group by m.p_c_id
) As SubA
Some of the other answers here won't work, since ordering by the now-varchar num_of_lights will put '8' after '15' as is happening now. You want to order the numLights numerically, which isn't going to happen with those html tags around them. You can add a subselect to your subselect so that you order them, then select them with the tags around them. Example (not tested):
SELECT * FROM (
select distinct
m.p_c_id
,(select distinct '<li>' +convert(varchar,num_of_lights) + '<br> '
from (select distinct p_c_id, num_of_lights from dbo.spec_master order by num_of_lights) m2
where m.p_c_id = m2.p_c_id and num_of_lights is not null
for xml path(''), type).value('.[1]', 'nvarchar(max)'
) as numLights_spec
from dbo.spec_master m
inner join dbo.ProductVaration pv on pv.p_c_id = m.p_c_id
inner join dbo.Varation v on v.varation_id = pv.varation_type_id
where v.varation_id = 4
group by m.p_c_id
Personally, I'd just add the html tags in whatever back-end code is getting the result of the query.