Get Multiple Select Query Value as a Table - tsql

I am using a stored procedure in which I am using multiple select statements, but these statements are returning the values as multiple result sets, but I want the return value in a single result set.
Here is my procedure:
Create Proc GetRequestDetail
As
Begin
Select Count(ReceiverId) As GetInvitation
From Requests
Where ReceiverId = 1044
Select Count(SenderId) As GetSendInvitation
From Requests
Where SenderId = 10
Select Count(ID) As GetAcceptedRequest
From Requests
Where ReceiverId = 7 And Status = 2735
Select Count(ID) As GetRejectedRequest
From Requests
Where ReceiverId = 2182 And Status = 2736
Select Count(ID) As GetAcceptRequest
From Requests
Where SenderId = 10 And status = 1255
Select Count(ID) As GetrejectRequest
From Requests
Where SenderId = 10 And status = 1256
end

If all results need to be in the same row:
ALTER PROCEDURE GetRequestDetail
as
begin
SELECT
GetInvitation = (Select Count(ReceiverId) from Requests Where ReceiverId = 1044 ),
GetSendInvitation = (Select Count(SenderId) from Requests Where SenderId = 10),
GetAcceptedRequest = (Select Count(ID) from Requests where ReceiverId = 7 and Status = 2735),
GetRejectedRequest = (Select Count(ID) as GetRejectedRequest from Requests where ReceiverId = 2182 and Status = 2736),
GetAcceptRequest = (Select Count(ID) as GetAcceptRequest from Requests where SenderId = 10 and status = 1255),
GetrejectRequest = (Select Count(ID) as GetrejectRequest from Requests where SenderId = 10 and status = 1256)
end
On a side note, it seems that you are missing paramters to your SP (maybe receiving the searched IDs as parameters?). Could be something like the following:
ALTER PROCEDURE GetRequestDetail
#ReceivedID INT,
#SenderID INT
as
begin
SELECT
GetInvitation = (Select Count(ReceiverId) from Requests Where ReceiverId = #ReceivedID ),
GetSendInvitation = (Select Count(SenderId) from Requests Where SenderId = #SenderID),
GetAcceptedRequest = (Select Count(ID) from Requests where ReceiverId = #ReceivedID and Status = 2735),
GetRejectedRequest = (Select Count(ID) as GetRejectedRequest from Requests where ReceiverId = #ReceivedID and Status = 2736),
GetAcceptRequest = (Select Count(ID) as GetAcceptRequest from Requests where SenderId = #SenderID and status = 1255),
GetrejectRequest = (Select Count(ID) as GetrejectRequest from Requests where SenderId = #SenderID and status = 1256)
end

Related

View query without sub selecting T-SQL

so I'm trying to build a view query but I keep failing using only joins so I ended up with this deformation.. Any tips on how I can write this query so I don't have to use 6 subselects?
The FeeSum and PaymentSum can be null, so ideally I do not want those in my result set and I also wouldn't like results where the FeeSum and the PaymentSum are equal.
Quick note: client is the table where the clients informations are stored (name, adress, etc..)
customer has a fk on client and is kind of a shell table for the client that store more information for the client,
payment is a list of all payments a customer did,
order is a list of all orders a customer did.
The goal is to get a list where we can track which customer has open fees to pay, based on the orders. It's a legacy project so don't ask why people can order before paying :)
SELECT
cu.Id as [CustomerId]
, CASE
WHEN cl.IsPerson = 1
THEN cl.[AdditionalName] + ' ' + cl.[Name]
ELSE cl.AdditionalName
END as [Name]
, cl.CustomerNumber
, (SELECT SUM(o.Fee) FROM [publication].[Order] o WHERE o.[State] = 2 AND o.CustomerId = cu.Id) as [FeeSum]
, (SELECT SUM(p.Amount) FROM [publication].[Payment] p WHERE p.CustomerId = cu.Id) as [PaymentSum]
, (SELECT MAX(o.OrderDate) FROM [publication].[Order] o WHERE o.[State] = 2 AND o.CustomerId = cu.Id) as [LastOrderDate]
, (SELECT MAX(p.PaymentDate) FROM [publication].[Payment] p WHERE p.CustomerId = cu.Id) as [LastPaymentDate]
, (SELECT MAX(f.Created) FROM [client].[File] f WHERE f.TemplateName = 'Reminder' AND f.ClientId = cl.Id) as [LastReminderDate]
, (SELECT MAX(f.Created) FROM [client].[File] f WHERE f.TemplateName = 'Warning' AND f.ClientId = cl.Id) as [LastWarningDate]
FROM
[publication].[Customer] cu
JOIN
[client].[Client] cl
ON cl.Id = cu.ClientId
WHERE
cu.[Type] = 0
Thanks in advance and I hope I didn't do anything wrong.
Kind regards
You could rewrite the correlated subqueries to instead use joins:
SELECT
cu.Id AS [CustomerId],
CASE WHEN cl.IsPerson = 1
THEN cl.[AdditionalName] + ' ' + cl.[Name]
ELSE cl.AdditionalName END AS [Name],
cl.CustomerNumber,
o.FeeSum,
p.PaymentSum,
o.LastOrderDate,
p.LastPaymentDate,
f.LastReminderDate,
f.LastWarningDate
FROM [publication].[Customer] cu
INNER JOIN [client].[Client] cl
ON cl.Id = cu.ClientId
INNER JOIN
(
SELECT CustomerId, SUM(Fee) AS [FeeSum], MAX(OrderDate) AS [LastOrderDate]
FROM [publication].[Order]
WHERE o.[State] = 2
GROUP BY CustomerId
) o
ON o.CustomerId = cu.Id
INNER JOIN
(
SELECT CustomerId, SUM(Amount) AS [PaymentSum], MAX(PaymentDate) AS [LastPaymentDate]
FROM [publication].[Payment]
WHERE o.[State] = 2
GROUP BY CustomerId
) p
ON p.CustomerId = cu.Id
INNER JOIN
(
SELECT ClientId,
MAX(CASE WHEN TemplateName = 'Reminder' THEN Created END) AS [LastReminderDate],
MAX(CASE WHEN TemplateName = 'Warning' THEN Created END) AS [LastWarningDate]
FROM [client].[File]
GROUP BY ClientId
) f
ON f.ClientId = cl.Id
WHERE
cu.[Type] = 0;

Modifying a query to work with multiple users using SEDE

I am having a hard time getting my query to do what I want it to do...
If I run it for one UserId: 2140173 it seems to be working fine
Select UserId,
(Select Count(VoteTypeId) From SuggestedEditVotes where UserId = 2140173) as 'Total',
(Select Count(VoteTypeId) From SuggestedEditVotes where UserId = 2140173 and VoteTypeId = 2) As 'Accepted',
(Select Count(VoteTypeId) From SuggestedEditVotes where UserId = 2140173 and VoteTypeId = 3) As 'Rejected'
from SuggestedEditVotes
inner join Users on SuggestedEditVotes.UserId = Users.Id
where Users.Reputation > 2000 and UserId = 2140173
group by UserId
having Count(VoteTypeId) > 0
it returns
UserId Total Accepted Rejected
2140173 2230 1145 1085
But when I am trying to modify it slightly and run it for all users with more than 2000 reputation it does not give me the correct results :/
I am stuck with the sub Select statements as I am not sure what to put in their where clause..
This is what I have tried but it returns the totals and I want it to be a count for each user Id
Select UserId,
(Select Count(VoteTypeId) From SuggestedEditVotes) as 'Total',
(Select Count(VoteTypeId) From SuggestedEditVotes where VoteTypeId = 2) As 'Accepted',
(Select Count(VoteTypeId) From SuggestedEditVotes where VoteTypeId = 3) As 'Rejected'
from SuggestedEditVotes
inner join Users on SuggestedEditVotes.UserId = Users.Id
where Users.Reputation > 2000
group by UserId
having Count(VoteTypeId) > 0
Can anyone help?
NOTE: https://data.stackexchange.com/stackoverflow/query/new
Try this:
SELECT UserId,
COUNT(VoteTypeId) AS 'Total',
COUNT(
CASE
WHEN VoteTypeId = 2
THEN VoteTypeId
ELSE NULL
END) AS 'Accepted',
COUNT(
CASE
WHEN VoteTypeId = 3
THEN VoteTypeId
ELSE NULL
END) AS 'Rejected'
FROM SuggestedEditVotes
INNER JOIN Users
ON SuggestedEditVotes.UserId = Users.Id
WHERE Users.Reputation > 2000
GROUP BY UserId
HAVING COUNT(VoteTypeId) > 0

Error: Update with select in MySQL 5

Next everybody, I'm trying to make a query (UPDATE) to debit credits in XX (value) of a company identified by script_id + cnpj.
Ie, the value will dynamically and identification of the company as well.
 
When I run the following error appears:
[Err] 1093 - You can not specify target table 'company' for update in FROM clause
 
Already googled, tried to optimize the code, but did not see another way to perform this query.
UPDATE empresa
SET saldo = saldo - (
SELECT
preco
FROM
preco_servico
WHERE
id = (
SELECT
emp2.idEscritorio
FROM
empresa AS emp2
WHERE
razao_social = (
SELECT
emp3.associacao
FROM
empresa AS emp3
WHERE
idEscritorio = (
SELECT
certidao_contratada.empresa_idEscritorio AS idEscritorio
FROM
certidao_contratada
INNER JOIN certidao_processada ON certidao_contratada.cnpj_idCnpj = certidao_processada.certidao_contratada_cnpj_idCnpj
WHERE
certidao_processada.certidao_contratada_scripts_idScript = 68 #script_id
AND certidao_processada.certidao_contratada_cnpj_idCnpj = '34.997.015/0001-98' #cnpj (da certidão)
ORDER BY
certidao_processada.dataHoraConcluido DESC
LIMIT 1
)
)
)
AND tipo_servico LIKE 'b%'
)
WHERE
emp1.idEscritorio = (
SELECT
certidao_contratada.empresa_idEscritorio AS idEscritorio
FROM
certidao_contratada
INNER JOIN certidao_processada ON certidao_contratada.cnpj_idCnpj = certidao_processada.certidao_contratada_cnpj_idCnpj
WHERE
certidao_processada.certidao_contratada_scripts_idScript = 68 #script_id
AND certidao_processada.certidao_contratada_cnpj_idCnpj = '34.997.015/0001-98' #cnpj (da certidão)
ORDER BY
certidao_processada.dataHoraConcluido DESC
LIMIT 1
);`

The multi-part identifier "..." could not be bound

I get error (The multi-part identifier "f.FormID" could not be bound.) running this query:
select f.FormID, f.Title, fv.UserName
from Forms f join (
SELECT FormID
FROM Reports
WHERE (ReportID = #ReportID)
UNION
SELECT FormRelations.ForigenFormID
FROM FormRelations INNER JOIN
Forms ON FormRelations.ForigenFormID = Forms.FormID
WHERE (FormRelations.PrimaryFormID =
(SELECT FormID
FROM Reports
WHERE (ReportID = #ReportID)))
) ids
on f.FormID = ids.FormID
LEFT OUTER JOIN (select top 1 UserName, FormID from FormValues where FormID = f.FormID and UserName = #UserName) fv
ON f.FormID = fv.FormID
Please someone help me :(
#bluefeet:
I want such a result:
01304636-FABE-4A3E-9487-A14B012F9A61 item_1 1234567890
C0455E97-788A-4305-876A-A15000CFE928 item_2 1234567890
7719F37E-7021-4ABD-91ED-A15301830324 item_3 1234567890
If you need to use your alias inside of your subquery like that, you might want to look at using the APPLY operator:
select f.FormID, f.Title, fv.UserName
from Forms f
join
(
SELECT FormID
FROM Reports
WHERE (ReportID = #ReportID)
UNION
SELECT FormRelations.ForigenFormID
FROM FormRelations
INNER JOIN Forms
ON FormRelations.ForigenFormID = Forms.FormID
WHERE (FormRelations.PrimaryFormID = (SELECT FormID
FROM Reports
WHERE (ReportID = #ReportID)))
) ids
on f.FormID = ids.FormID
CROSS APPLY
(
select top 1 UserName, FormID
from FormValues
where FormID = f.FormID
and UserName = #UserName
) fv
Or you can use row_number():
select f.FormID, f.Title, fv.UserName
from Forms f
join
(
SELECT FormID
FROM Reports
WHERE (ReportID = #ReportID)
UNION
SELECT FormRelations.ForigenFormID
FROM FormRelations
INNER JOIN Forms
ON FormRelations.ForigenFormID = Forms.FormID
WHERE (FormRelations.PrimaryFormID = (SELECT FormID
FROM Reports
WHERE (ReportID = #ReportID)))
) ids
on f.FormID = ids.FormID
LEFT JOIN
(
select UserName, FormID,
ROW_NUMBER() over(PARTITION by FormID, UserName order by FormID) rn
from FormValues
where UserName = #UserName
) fv
on f.FormID = fv.FormID
and fv.rn = 1

combine two sql sets of results while using TOP

I have these two queries and I want one set of results combining top 5 results for TP and top 5 results for LP.
I really do not know how to explain this more clearly, I have two sets of results, top 5 for LP and top 5 for TP and I would like to have a set of results Incident_TP, IncidentID_TP, IncidentHappenedDate_TP , IncidentNumber_TP , LossValue_TP , RecoveredValue_TP , TotalLoss_TP , Incident_LP, IncidentID_LP, IncidentHappenedDate_LP , IncidentNumber_LP , LossValue_LP , RecoveredValue_LP , TotalLoss_LP
DECLARE #IncidentFromDate_TP DATE = '2011-1-12'
DECLARE #IncidentToDate_TP DATE = '2012-1-12'
DECLARE #IncidentFromDate_LP DATE = '2010-1-12'
DECLARE #IncidentToDate_LP DATE = '2011-1-12'
SELECT TOP 5
Incident_TP = Incident_TP.IncidentID
, IncidentHappenedDate_TP = Incident_TP.IncidentHappenedDate
, IncidentNumber_TP = Incident_TP.IncidentNumber
, LossValue_TP = Incident_TP.TotalLoss
, RecoveredValue_TP = Incident_TP.TotalRecovered
, TotalLoss_TP = Incident_TP.CostOfIncident
FROM
Incident AS Incident_TP
INNER JOIN Site AS Site_TP ON Incident_TP.SiteID = Site_TP.SiteID
INNER JOIN Region AS Region_TP ON Site_TP.RegionID = Region_TP.RegionID
WHERE
Incident_TP.TotalLoss > 0.00
AND Incident_TP.IncidentHappenedDate BETWEEN #IncidentFromDate_TP AND #IncidentToDate_TP
ORDER BY
TotalLoss_TP DESC
, IncidentHappenedDate_TP DESC
SELECT TOP 5
Incident_LP = Incident_LP.IncidentID
, IncidentHappenedDate_LP = Incident_LP.IncidentHappenedDate
, IncidentNumber_LP = Incident_LP.IncidentNumber
, LossValue_LP = Incident_LP.TotalLoss
, RecoveredValue_LP = Incident_LP.TotalRecovered
, TotalLoss_LP = Incident_LP.CostOfIncident
FROM
Incident AS Incident_LP
INNER JOIN Site ON Incident_LP.SiteID = Site.SiteID
INNER JOIN Region ON Site.RegionID = Region.RegionID
WHERE
Incident_LP.TotalLoss > 0.00
AND Incident_LP.IncidentHappenedDate BETWEEN #IncidentFromDate_LP AND #IncidentToDate_TP
ORDER BY
TotalLoss_LP DESC
, IncidentHappenedDate_LP DESC
Many thanks
As Tim suggests you could union the sets together, For example:
DECLARE #IncidentFromDate_TP DATE = '2011-1-12';
DECLARE #IncidentToDate_TP DATE = '2012-1-12';
DECLARE #IncidentFromDate_LP DATE = '2010-1-12';
DECLARE #IncidentToDate_LP DATE = '2011-1-12';
WITH RawData
AS ( SELECT Incident_TP = Incident_TP.IncidentID ,
IncidentHappenedDate_TP = Incident_TP.IncidentHappenedDate ,
IncidentNumber_TP = Incident_TP.IncidentNumber ,
LossValue_TP = Incident_TP.TotalLoss ,
RecoveredValue_TP = Incident_TP.TotalRecovered ,
TotalLoss_TP = Incident_TP.CostOfIncident
FROM Incident AS Incident_TP
INNER JOIN Site AS Site_TP ON Incident_TP.SiteID = Site_TP.SiteID
INNER JOIN Region AS Region_TP ON Site_TP.RegionID = Region_TP.RegionID
WHERE Incident_TP.TotalLoss > 0.00
),
TopFiveSetA
AS ( SELECT TOP 5
*
FROM RawData
WHERE IncidentHappenedDate_TP BETWEEN #IncidentFromDate_TP
AND #IncidentToDate_TP
ORDER BY TotalLoss_TP DESC ,
IncidentHappenedDate_TP DESC
),
TopFiveSetB
AS ( SELECT TOP 5
*
FROM RawData
WHERE IncidentHappenedDate_TP BETWEEN #IncidentFromDate_LP
AND #IncidentToDate_LP
ORDER BY TotalLoss_TP DESC ,
IncidentHappenedDate_TP DESC
),
Merged
AS ( SELECT *
FROM TopFiveSetA
UNION ALL
SELECT *
FROM TopFiveSetB
)
SELECT *
FROM Merged