SQL Server 2008 left join where clause based on max date - sql-server-2008

Got some help the other day on this and now really want to make a change for the better
Here is code
select
machines.serialnum, DRPS.assetnumber, DRPS.MOCALCSUM, DRPS.MICALCSUM,
DRPS.COCALCSUM, DRPS.CICALCSUM, ISSUED.TotalIssued,
REDEEMED.TotalRedeemed,drps.dropdate1,drps.dropdate2
from
(select serialnum
from machineinfo) as machines
LEFT JOIN
(select
assetnumber, min(dropdate) as [dropdate1], max(dropdate) as [dropdate2],
sum(mocalc) AS [MOCALCSUM], sum(micalc) AS [MICALCSUM],
sum(cocalc) AS [COCALCSUM],sum(cicalc) AS [CICALCSUM]
from drops
where dropdate > '09/04/2012' and dropdate < dateadd(hour, -0, getdate())
GROUP BY assetnumber) AS DRPS on machines.serialnum = drps.assetnumber
LEFT JOIN
(select
snissued, cast(sum(amount) as money) / 100 AS [TotalIssued]
from tickets
where dateissued > '09/04/2012' and dateissued < dateadd(hour, 0, getdate())
group by snissued) AS ISSUED ON machines.serialnum = ISSUED.snissued
LEFT JOIN
(select
snredeemed, cast(sum(amount) as money) / 100 AS [TotalRedeemed]
from tickets
where dateredeemed > '09/04/2012' and dateredeemed < dateadd(hour, 0, getdate())
group by snredeemed) AS REDEEMED ON machines.serialnum = REDEEMED.snredeemed
what I would like to accomplish if possible is for the second and third join is to use the drps.drop1 in the where clause like this
where dropdate > drps.dropdate1 and dropdate < drps.dropdate2
but it does not work
here is working output
serialnum MOCALCSUM MICALCSUM COCALCSUM CICALCSUM TotalIssued TotalRedeemed dropdate1 dropdate2
0-2739-41401 5482 5498 132 148 3258.00 3110.00 2012-09-04 13:36:53.450 2012-09-05 13:55:38.750
0-2459-36182 1110 1054 114 58 1895.00 1657.00 2012-09-04 15:01:19.973 2012-09-05 13:55:38.967
end result is I need total issued and total redeemed date range to be between the min and max date per serial number

declare #datebegin datetime
declare #dateend datetime
set #datebegin = '09/04/2012'
set #dateend = '09/08/2012'
select machines.serialnum, DRPS.MOCALCSUM,DRPS.MICALCSUM,DRPS.COCALCSUM,DRPS.CICALCSUM,ISSUED.TotalIssued,
REDEEMED.TotalRedeemed,drps.dropdate1,drps.dropdate2
from (select serialnum
from machineinfo) as machines
LEFT JOIN (select assetnumber,min(dropdate)as [dropdate1], max(dropdate)as [dropdate2], sum(mocalc) AS [MOCALCSUM],sum(micalc) AS [MICALCSUM],
sum(cocalc) AS [COCALCSUM],sum(cicalc) AS [CICALCSUM]
from drops
where dropdate > #datebegin and dropdate < #dateend AND (ignore is null)
group by assetnumber) AS DRPS
on machines.serialnum = drps.assetnumber
LEFT JOIN (select snissued,cast(sum(amount)as money)/100 AS [TotalIssued] from tickets
where (dateissued > (select min(dropdate)
from drops
where dropdate > #datebegin AND (ignore is null) and snissued = assetnumber ))
and
(dateissued < (select max(dropdate)
from drops
where dropdate < #dateend AND (ignore is null) and snissued = assetnumber))
group by snissued) AS ISSUED
ON machines.serialnum=ISSUED.snissued
LEFT JOIN (select snredeemed,cast(sum(amount)as money)/100 AS [TotalRedeemed]
from tickets
where (dateredeemed > (select min(dropdate)
from drops
where dropdate > #datebegin AND (ignore is null)and snissued = assetnumber))
and
(dateredeemed < (select max(dropdate)
from drops
where dropdate < #dateend AND (ignore is null)and snissued = assetnumber ))
group by snredeemed) AS REDEEMED
ON machines.serialnum=REDEEMED.snredeemed
order by REDEEMED.TotalRedeemed desc
based on the suggestion from comments i added the subquery into the selects and i am getting expected results now

Related

SQL how to create aggregate of two aggregated columns for each row

I'm working on a big query in SQL (MySQL 5.7) to calculate aggregated columns based on raw values in my table. I've created several aggregated columns (see attached screenshot and SQL) and I now need to create a conversion_percent column for each tlp_aff_id in my query.
This conversion_percent should be a division of the aggregated JoinedSessions.total_sessions and COUNT(Report.tlp_aff_id) as leads_total.
My current SQL:
SELECT
# Application details
Report.tlp_aff_id,
# Revenue
JoinedRevenue.total_revenue,
# Commission
JoinedCommission.total_commission,
# Profit
JoinedProfit.total_profit,
# Sessions
JoinedSessions.total_sessions,
# Submits
COUNT(Report.tlp_aff_id) as total_submits,
# Leads
COUNT(Report.tlp_aff_id) as leads_total,
SUM(case when Report.application_result = 'Accepted' then 1 else 0 end) leads_accepted,
SUM(case when Report.application_result = 'Rejected' then 1 else 0 end) leads_rejected
# Conversion percent
# JoinedConversion.conversion_percent
FROM
tlp_payout_report_minute AS Report
INNER JOIN
(
SELECT
JoinedRevenue.tlp_aff_id,
JoinedRevenue.minute_rounded_timestamp,
SUM(commission) AS total_revenue
FROM
tlp_payout_report_minute AS JoinedRevenue
WHERE
JoinedRevenue.minute_rounded_timestamp >= 1664841600
AND
JoinedRevenue.minute_rounded_timestamp <= 1664927999
GROUP BY
JoinedRevenue.tlp_aff_id
) AS JoinedRevenue
ON JoinedRevenue.tlp_aff_id = Report.tlp_aff_id
INNER JOIN
(
SELECT
ReportCommission.tlp_aff_id,
ReportCommission.seller_code,
ReportCommission.minute_rounded_timestamp,
SUM(commission) AS total_commission
FROM
tlp_payout_report_minute AS ReportCommission
WHERE
ReportCommission.minute_rounded_timestamp >= 1664841600
AND
ReportCommission.minute_rounded_timestamp <= 1664927999
AND
ReportCommission.seller_code != 44
GROUP BY
ReportCommission.tlp_aff_id
) AS JoinedCommission
ON JoinedCommission.tlp_aff_id = Report.tlp_aff_id
INNER JOIN
(
SELECT
ReportProfit.tlp_aff_id,
ReportProfit.seller_code,
ReportProfit.application_result,
ReportProfit.minute_rounded_timestamp,
SUM(commission) AS total_profit
FROM
tlp_payout_report_minute AS ReportProfit
WHERE
ReportProfit.minute_rounded_timestamp >= 1664841600
AND
ReportProfit.minute_rounded_timestamp <= 1664927999
AND
ReportProfit.application_result = 'Accepted'
AND
ReportProfit.seller_code = 44
GROUP BY
ReportProfit.tlp_aff_id
) AS JoinedProfit
ON JoinedProfit.tlp_aff_id = Report.tlp_aff_id
INNER JOIN
(
SELECT
Conversion.aff_id,
Conversion.conversion_type,
COUNT(Conversion.ip_address) as total_sessions
FROM
tlp_conversions AS Conversion
WHERE
Conversion.conversion_time >= '2022-10-04 00:00:00'
AND
Conversion.conversion_time <= '2022-10-04 23:59:59'
AND
Conversion.aff_id IS NOT NULL
AND
Conversion.conversion_type = 2
GROUP BY
Conversion.aff_id
) AS JoinedSessions
ON JoinedSessions.aff_id = Report.tlp_aff_id
WHERE
Report.minute_rounded_timestamp >= 1664841600
AND
Report.minute_rounded_timestamp <= 1664927999
GROUP BY
Report.tlp_aff_id
ORDER BY
JoinedRevenue.total_revenue DESC
I'm thinking something along the lines of:
INNER JOIN
(
...
) AS JoinedConversion
ON JoinedConversion.aff_id = Report.tlp_aff_id
But I don't think this is necessary for conversion_percent.
What's the right approach here?

Script is freezing. Want to take the average count of "Women" for 1 month ago to 60 months ago. This portion of the code is freezing on me

/*This is the code Im using to count and take the Average?*/
`SELECT GETDATE() AS CurrentDate,
(SELECT COUNT(1) FROM People WITH(NOLOCK) LEFT JOIN LinkPeopleToCompanies WITH(NOLOCK) ON
People.PeopleID = LinkPeopleToCompanies.PeopleID
WHERE (LinkPeopleToCompanies.ToDate >= GETDATE() OR LinkPeopleToCompanies.ToDate IS NULL)
AND LinkPeopleToCompanies.SinceDate <= GETDATE() - 2190
AND LinkPeopleToCompanies.CompaniesID = Companies.CompaniesID) AS TotalDirectorsAddedin6years,
(SELECT AVG(DATEDIFF("yyyy",People.BirthDay,GETDATE())) FROM People WITH(NOLOCK) LEFT JOIN
LinkPeopleToCompanies WITH(NOLOCK) ON People.PeopleID = LinkPeopleToCompanies.PeopleID
WHERE (LinkPeopleToCompanies.ToDate >= GETDATE() - 30 OR LinkPeopleToCompanies.ToDate IS NULL)
AND LinkPeopleToCompanies.SinceDate <= GETDATE() - 30
AND LinkPeopleToCompanies.CompaniesID = Companies.CompaniesID) AS AverageDirectorAge1MonthAgo,
/I repeat this same code going back progressively by 30 days or 1 month. Need some more effective code/
(SELECT AVG(LinkPeopleToCompanies.CustomInt1) FROM People WITH(NOLOCK) LEFT JOIN
LinkPeopleToCompanies WITH(NOLOCK) ON People.PeopleID = LinkPeopleToCompanies.PeopleID
WHERE (LinkPeopleToCompanies.ToDate >= GETDATE() - 30 OR LinkPeopleToCompanies.ToDate IS NULL)
AND LinkPeopleToCompanies.SinceDate <= GETDATE() - 30
AND LinkPeopleToCompanies.CompaniesID = Companies.CompaniesID) AS AverageDirectorTenure1MonthAgo,
TotalWomenonBoard1 = CASE WHEN ((SELECT COUNT(1) FROM People WITH(NOLOCK) INNER JOIN
LinkPeopleToCompanies WITH(NOLOCK) ON People.PeopleID = LinkPeopleToCompanies.PeopleID
WHERE (LinkPeopleToCompanies.ToDate >= GETDATE()- 30 OR LinkPeopleToCompanies.ToDate IS NULL)
AND LinkPeopleToCompanies.SinceDate <= GETDATE()- 30
AND LinkPeopleToCompanies.CompaniesID = Companies.CompaniesID) = 0 )
THEN '9999999'
ELSE (SELECT COUNT(1) FROM People WITH(NOLOCK) INNER JOIN LinkPeopleToCompanies WITH(NOLOCK) ON
People.PeopleID = LinkPeopleToCompanies.PeopleID
WHERE (LinkPeopleToCompanies.ToDate >= GETDATE() - 30 OR LinkPeopleToCompanies.ToDate IS NULL)
AND LinkPeopleToCompanies.SinceDate <= GETDATE() - 30
AND LinkPeopleToCompanies.CompaniesID = Companies.CompaniesID
AND People.Gender = 'F')
END,
TotalWomenonBoard2 = CASE WHEN ((SELECT COUNT(1) FROM People WITH(NOLOCK) INNER JOIN
LinkPeopleToCompanies WITH(NOLOCK) ON People.PeopleID = LinkPeopleToCompanies.PeopleID
WHERE (LinkPeopleToCompanies.ToDate >= GETDATE()- 60 OR LinkPeopleToCompanies.ToDate IS NULL)
AND LinkPeopleToCompanies.SinceDate <= GETDATE()- 60
AND LinkPeopleToCompanies.CompaniesID = Companies.CompaniesID) = 0 )
THEN '9999999'
ELSE (SELECT COUNT(1) FROM People WITH(NOLOCK) INNER JOIN LinkPeopleToCompanies WITH(NOLOCK) ON
People.PeopleID = LinkPeopleToCompanies.PeopleID
WHERE (LinkPeopleToCompanies.ToDate >= GETDATE() - 60 OR LinkPeopleToCompanies.ToDate IS NULL)
AND LinkPeopleToCompanies.SinceDate <= GETDATE() - 60
AND LinkPeopleToCompanies.CompaniesID = Companies.CompaniesID
AND People.Gender = 'F')
END,
TotalWomenonBoard60 = CASE WHEN ((SELECT COUNT(1) FROM People WITH(NOLOCK) INNER JOIN
LinkPeopleToCompanies WITH(NOLOCK) ON People.PeopleID = LinkPeopleToCompanies.PeopleID
WHERE (LinkPeopleToCompanies.ToDate >= GETDATE()- 1825 OR LinkPeopleToCompanies.ToDate IS NULL)
AND LinkPeopleToCompanies.SinceDate <= GETDATE()- 1825
AND LinkPeopleToCompanies.CompaniesID = Companies.CompaniesID) = 0 )
THEN '9999999'
ELSE (SELECT COUNT(1) FROM People WITH(NOLOCK) INNER JOIN LinkPeopleToCompanies WITH(NOLOCK) ON
People.PeopleID = LinkPeopleToCompanies.PeopleID
WHERE (LinkPeopleToCompanies.ToDate >= GETDATE()- 1825 OR LinkPeopleToCompanies.ToDate IS NULL)
AND LinkPeopleToCompanies.SinceDate <= GETDATE()- 1825
AND LinkPeopleToCompanies.CompaniesID = Companies.CompaniesID
AND People.Gender = 'F')
END
FROM Companies WITH(NOLOCK)
ORDER BY Company`
Syntax in the question appears to be Transact-SQL ala Microsoft SQL Server (which is different than MySQL and Oracle; this question seems to be unrelated to the actual client program, that detail might be important... setting that aside.
For performance, I would opt to use conditional aggregation. I would use a single SELECT and one set of table references, and avoid multiple SELECT queries against the same tables with different WHERE clauses.
To get a count of "some" rows, I'd use a conditional in an expression to return a 1 or 0, and then total those up with SUM. (Or, I return a non-null and NULL, and use COUNT.)
Without digging into every SELECT ... FROM included in the question, it looks like the only form of statement we need is this:
SELECT GETDATE() AS CurrentDate
, SUM(CASE WHEN ... THEN 1 ELSE 0 END) AS stat_count_foo
FROM Companies c
LEFT
JOIN LinkPeopleToCompanies t
ON t.companiesid = c.companiesid
LEFT
JOIN People p
ON p.peopleid = t.peopleid
GROUP
BY c.companiesid
Note that there is not a WHERE clause in there. (We would only include conditions in the WHERE clause to exclude rows that we don't need for any metrics.)
Adding some example metrics, our statement would look something like this:
SELECT GETDATE() AS CurrentDate
, SUM( CASE
WHEN (t.todate >= GETDATE() OR t.todate IS NULL)
AND t.sincedate <= GETDATE() - 2190
THEN 1
ELSE 0
END
) AS TotalDirectorsAddedin6years
, AVG( CASE
WHEN (t.todate >= GETDATE() - 30 OR t.todate IS NULL)
AND t.sincedate <= GETDATE() - 30
THEN DATEDIFF('yyyy',p.birthDay,GETDATE())
ELSE NULL
END
) AS AverageDirectorAge1MonthAgo
, SUM( CASE
WHEN (t.todate >= GETDATE()- 1825 OR t.todate IS NULL)
AND t.sincedate <= GETDATE()- 1825
AND p.Gender = 'F'
THEN 1
ELSE 0
END
) AS TotalWomenonBoard60
FROM Companies c
LEFT
JOIN LinkPeopleToCompanies t
ON t.companiesid = c.companiesid
LEFT
JOIN People p
ON p.peopleid = t.peopleid
GROUP
BY c.companiesid
Extend this by adding additional expressions. Do NOT add any additional SELECT, FROM or JOIN keywords. We could wrap the aggregate expressions in another expression to replace a NULL value with a "0" (for a company that doesn't have any people linked to it.

Query using group by month

I have problem with the query using group by month. This query returns total_revenue per month. but if month of year doesn't contain any data then total_revnue is increased unnecessarily.
SELECT COUNT(CT.cumTxnReportId),
CT.cumTxnReportId,
CT.ticketNum,
DATE_FORMAT(CT.exitDateTimeUtc,'%m-%Y'),
sum(netAmount) AS total_revenue,
D.name,
HOUR(CT.entranceDateTimeUtc) AS entryHour,
HOUR(CT.exitDateTimeUtc) AS exitHour,
CT.entranceDateTimeUtc,
CT.exitDateTimeUtc,
CT.netAmount AS netAmount,
CT.grossAmount,
CT.discountAmount,
CT.rate,
CT.txnType,
CT.ticketType,
CT.txnNum,
CT.numDiscounts
FROM Parkloco.ParkingArea PA
JOIN IParcPro.Device D ON PA.id = D.parkingAreaId
JOIN Parkloco.RateCard RC ON PA.id = RC.parkingAreaId
JOIN IParcPro.CumTxn CT ON D.id = CT.deviceId
WHERE PA.uuid = '27d842c1-7057-11e6-a0eb-1245b0d35d23'
AND (CT.txnType = 'Allowed'
OR CT.txnType = 'Add'
OR CT.txnType = 'Normal'
OR CT.txnType = 'Offline'
OR CT.txnType = 'Repay')
AND ((CT.entranceDateTimeUtc >= '2016-08-01 00:00:00'
AND CT.exitDateTimeUtc <= '2017-04-31 23:59:59'))
AND (RC.state = 'active'
OR RC.state = 'archived')
AND RC.fromDateTimeUtc <= '2017-04-31 23:59:59'
AND (RC.thruDateTimeUtc IS NULL
OR RC.thruDateTimeUtc >= '2016-08-01 00:00:00')
AND (TIMESTAMPDIFF (SECOND, CT.entranceDateTimeUtc, CT.exitDateTimeUtc) >= '0' * 60)
AND (TIMESTAMPDIFF (SECOND, CT.entranceDateTimeUtc, CT.exitDateTimeUtc) < '1441' * 60)
AND CT.numDiscounts=0
AND CT.ticketNum !=0
GROUP BY DATE_FORMAT(CT.exitDateTimeUtc,'%m-%Y')
but when I am increasing the range month - at that point of time I am getting unneccessary increment in total_revenue
SELECT COUNT(CT.cumTxnReportId),
CT.cumTxnReportId,
CT.ticketNum,
DATE_FORMAT(CT.exitDateTimeUtc,'%m-%Y'),
sum(netAmount) AS total_revenue,
D.name,
HOUR(CT.entranceDateTimeUtc) AS entryHour,
HOUR(CT.exitDateTimeUtc) AS exitHour,
CT.entranceDateTimeUtc,
CT.exitDateTimeUtc,
CT.netAmount AS netAmount,
CT.grossAmount,
CT.discountAmount,
CT.rate,
CT.txnType,
CT.ticketType,
CT.txnNum,
CT.numDiscounts
FROM Parkloco.ParkingArea PA
JOIN IParcPro.Device D ON PA.id = D.parkingAreaId
JOIN Parkloco.RateCard RC ON PA.id = RC.parkingAreaId
JOIN IParcPro.CumTxn CT ON D.id = CT.deviceId
WHERE PA.uuid = '27d842c1-7057-11e6-a0eb-1245b0d35d23'
AND (CT.txnType = 'Allowed'
OR CT.txnType = 'Add'
OR CT.txnType = 'Normal'
OR CT.txnType = 'Offline'
OR CT.txnType = 'Repay')
AND ((CT.entranceDateTimeUtc >= '2016-08-01 00:00:00'
AND CT.exitDateTimeUtc <= '2017-07-31 23:59:59'))
AND (RC.state = 'active'
OR RC.state = 'archived')
AND RC.fromDateTimeUtc <= '2017-07-31 23:59:59'
AND (RC.thruDateTimeUtc IS NULL
OR RC.thruDateTimeUtc >= '2016-08-01 00:00:00')
AND (TIMESTAMPDIFF (SECOND, CT.entranceDateTimeUtc, CT.exitDateTimeUtc) >= '0' * 60)
AND (TIMESTAMPDIFF (SECOND, CT.entranceDateTimeUtc, CT.exitDateTimeUtc) < '1441' * 60)
AND CT.numDiscounts=0
AND CT.ticketNum !=0
GROUP BY DATE_FORMAT(CT.exitDateTimeUtc,'%m-%Y')
output such as :
can anyone help me on this? Thanks in advance if you could let me know.
Despite MySQL allow this weird group by rules, in my opinion, you should to avoid use it. I explain, usually, all select clause non aggregate fields should appear on group by clause:
select a,b,c, sum(z)
from t
group by a,b,c
vs
select a,b,c, sum(z)
from t
group by a #<--- MySQL allow this!
Then, if b and c are not in group by, how MySQL figure up the right fields to be selected? Like this on <5.6:
The server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate.
In my opinion, in your query has no sense: Look entryHour and total_revenue. One is for an entry the other one is for all month.
I guess you should to rethink the hole sql statement. Because the result of this one is incoherent.
Also, remember this is not 'code revision service'. Please, read how to create a Minimal, Complete, and Verifiable example in order your question also help other users.

SQL Distinct Multiple Query Combine

I need to get information from two tables as you can see below but by shift so currently they are running basically the same query 4 times, 2 times for each shift.
For first shift they grab all carton numbers that are NOT EQUAL to DELC and the second query for all cartons EQUAL to DELC. The problem is we want distinct carton numbers and if the carton was half processed on first shift and finished on second shift, even though we are doing distinct the carton shows up twice because its only distinct for each query.
Is there a way to run ALL 4 queries together and do a distinct over the entire data?
1 Day old 1st shift = DELC
select count(distinct a.Barcode)
from [RL_Ship].[dbo].[mSCAN] as a inner join
[RL_Ship].dbo].wmsInboundQueue] on
a.barcode = substring(message,26,20)
Where BagToteFlag = 'Y' and direction = 'Send'
and timeStamp >= '2016-06-14 03:00:00'
and timeStamp < '2016-06-14 15:00:00'
and substring(message,64,4) = 'DELC'
and SUBSTRING(rawdata,21,20) > '0'
1 Day old 1st shift <> DELC
select count(distinct a.Barcode)
from [RL_Ship].[dbo].[mSCAN] as a inner join
[RL_Ship].dbo].wmsInboundQueue] on
a.barcode = substring(message,26,20)
Where a.BagToteFlag = 'Y' and a.direction = 'Send'
and a.timeStamp >= '2016-06-14 03:00:00'
and a.timeStamp < '2016-06-14 15:00:00'
and substring(message,64,4) <> 'DELC'
and SUBSTRING(rawdata,21,20) > '0'
1 Day old 2nd shift = DELC
select count(distinct a.Barcode)
from [RL_Ship].[dbo].[mSCAN] as a inner join [RL_Ship].[dbo].
[wmsInboundQueue] on
a.barcode = substring(message,26,20)
Where a.BagToteFlag = 'Y' and a.direction = 'Send'
and a.timeStamp >= '2016-06-14 15:00:00'
and a.timeStamp < '2016-06-15 03:00:00'
and substring(message,64,4) = 'DELC'
and SUBSTRING(rawdata,21,20) > '0'
1 Day old 2nd shift <> DELC
select count(distinct a.Barcode)
from [RL_Ship].[dbo].[mSCAN] as a inner join [RL_Ship].[dbo].
[wmsInboundQueue] on
a.barcode = substring(message,26,20)
Where a.BagToteFlag = 'Y' and a.direction = 'Send'
and a.timeStamp >= '2016-06-14 15:00:00'
and a.timeStamp < '2016-06-15 03:00:00'
and substring(message,64,4) <> 'DELC'
and SUBSTRING(rawdata,21,20) > '0'
If I have understood your question correct the first query I would have tried to get the result you want is something like
SELECT count(distinct barcode) FROM (
select distinct a.Barcode <rest of query>
UNION
select distinct a.Barcode <rest of next query>
UNION ... )
If I do a union and take off the count part I get the correct number as the duplicates are removed across ALL queries, but if I do a union and a count the number is off, it doesn't remove the duplicates.......
and I actually need a total count per query as they are different shifts/time ranges.
The answer of doing a count and then from is good but one I couldn't get that to work and 2 I think that is only going to give me a count off ALL right?
I tried the following but it gave me the following error:
Msg 156, Level 15, State 1, Line 36
Incorrect syntax near the keyword 'select'.
EDIT: Ok I got this working by adding 'as table1' at the end but as I suspected it is only giving me a total, but without duplicates, which is great but I need a count for each of the 4 queries. Any ideas on that?
select count(distinct Barcode) from
(select distinct a.barcode
from [RL_Ship].[dbo].[mSCAN] as a inner join [RL_Ship].[dbo].
[wmsInboundQueue] on
a.barcode = substring(message,26,20)
Where BagToteFlag = 'Y' and direction = 'Send'
and timeStamp >= '2016-06-14 03:00:00' and timeStamp < '2016-06-14
15:00:00'
and substring(message,64,4) = 'DELC'
and SUBSTRING(rawdata,21,20) > '0'
union
select distinct a.Barcode
from [RL_Ship].[dbo].[mSCAN] as a inner join [RL_Ship].[dbo].
[wmsInboundQueue] on
a.barcode = substring(message,26,20)
Where a.BagToteFlag = 'Y' and a.direction = 'Send'
and a.timeStamp >= '2016-06-14 03:00:00'
and a.timeStamp < '2016-06-14 15:00:00'
and substring(message,64,4) <> 'DELC'
and SUBSTRING(rawdata,21,20) > '0'
union
select distinct a.Barcode
from [RL_Ship].[dbo].[mSCAN] as a inner join [RL_Ship].[dbo].
[wmsInboundQueue] on
a.barcode = substring(message,26,20)
Where a.BagToteFlag = 'Y' and a.direction = 'Send'
and a.timeStamp >= '2016-06-14 15:00:00'
and a.timeStamp < '2016-06-15 03:00:00'
and substring(message,64,4) = 'DELC'
and SUBSTRING(rawdata,21,20) > '0'
union
select distinct a.Barcode
from [RL_Ship].[dbo].[mSCAN] as a inner join [RL_Ship].[dbo].
[wmsInboundQueue] on
a.barcode = substring(message,26,20)
Where a.BagToteFlag = 'Y' and a.direction = 'Send'
and a.timeStamp >= '2016-06-14 15:00:00'
and a.timeStamp < '2016-06-15 03:00:00'
and substring(message,64,4) <> 'DELC'
and SUBSTRING(rawdata,21,20) > '0')

SQL - Subquery Error and Sum Error

The SQL code I have is shown below. The issue I am having is with the subquery first of all.
The result displays the error:
SQL ERROR: Subquery returned more than 1 value. This is not permitted
when the subquery follows =, !=, <, <= , >, >= or when the subquery is
used as an expression
Need to show rows with date greater than (or equal to) the date where ESource = Detail - The rows need to be summed in some columns and a single value selected in others.
Code used:
select DISTINCT
A.Policy,
A.Fund,
(SUM(A.AddUnits)) AS SUM,
((C.TotalUnits - (SUM(A.AddUnits))) * A.Price) AS Value,
Inner JOIN TableC C
ON C.PolicyNumber = A.PolicyNumber
where A.PolicyNumber = '120' AND C.NumberOfUnits > 0 AND C.InvestmentFund = A.InvestmentFund
AND A.DateOfEntry < DATEADD(year, -1, GetDate())
AND A.DateOfEntry >= (Select DateOfEntry FROM TableA AS D where D.ESource = 'Detail')
AND A.UnitPrice = (Select UnitPrice FROM TableA AS E where E.ESource = 'Detail')
ORDER BY IH.DateOfEntry DESC
Tables are:
Table A:
Policy Fund Units Price ESource Date
120 BR 6 0.74 RE 2015
120 BR -100 0.72 Detail 2014
120 BR 6 0.71 RE 2013
TABLE C:
Policy Fund TotalUnits
120 BR 400
DESIRED RESULT:
Policy Fund Sum Price Value
120 BR [6+(-100)] = -94 0.72 [(400+(-94))*0.72] = 220.32
As well as the sub query issues - the command to get price = 0.72 [where ="Detail"] is stopping the sum of both rows occurring making Sum = -100 and not -94
Any help with the errors would be greatly appreciated
The problem is in your where clause:
where A.PolicyNumber = '120' AND
C.NumberOfUnits > 0 AND
C.InvestmentFund = A.InvestmentFund AND
A.DateOfEntry < DATEADD(year, -1, GetDate()) AND
A.DateOfEntry >= (Select DateOfEntry FROM TableA AS D where D.ESource = 'Detail') AND
A.UnitPrice = (Select UnitPrice FROM TableA AS E where E.ESource = 'Detail')
The last two clauses are the problem. One way to fix this is with the keywords ANY, SOME, or ALL:
where A.PolicyNumber = '120' AND
C.NumberOfUnits > 0 AND
C.InvestmentFund = A.InvestmentFund AND
A.DateOfEntry < DATEADD(year, -1, GetDate()) AND
A.DateOfEntry >= ALL (Select DateOfEntry FROM TableA AS D where D.ESource = 'Detail') AND
A.UnitPrice = ALL (Select UnitPrice FROM TableA AS E where E.ESource = 'Detail')
However, I prefer explicit aggregation:
where A.PolicyNumber = '120' AND
C.NumberOfUnits > 0 AND
C.InvestmentFund = A.InvestmentFund AND
A.DateOfEntry < DATEADD(year, -1, GetDate()) AND
A.DateOfEntry >= (Select MAX(DateOfEntry) FROM TableA AS D where D.ESource = 'Detail') AND
A.UnitPrice = (Select MAX(UnitPrice) FROM TableA AS E where E.ESource = 'Detail')
Note that the query in your question seems to be missing a from clause. And the condition C.InvestmentFund = A.InvestmentFun should be in an on clause not in the where clause.