Conditional AND statement based on results of COUNT() - sql

I'm getting lost in a query's logic, and I need some help. To start, I have a parent table Campaigns. Then, a child table CampaignParks that looks like this:
select * from CampaignParks
For business reasons I won't bore you with, we need to include Parks in the Campaign table even if they are not included in the Campaign. To actually include them in the campaign, there is a flag for that. None, one, or multiple Parks might be set to Include In Campaign.
Ok. Simple enough. Now...
Given a #ParkID, I need to return all parent Campaigns where the ParkID is a match, but ONLY if one (or more) of the IncludeInCampaign flags for the campaign has been set. If no IncludeInCampaign flags for a given campaign have been set, then we just ignore the value of #Parks. We don't care about it.
Examples:
#ParkID = 11070. We get back 4 & 1
#ParkID = 11526. We get back 1
#ParkID = 26496. We get back 1
#ParkID = null. We get back 4 & 1
ParkID = 69. We get back 1.
So, I think the query would look something like this:
SELECT
DISTINCT
sc.ContactID,
cp.*
FROM
Campaigns sc
JOIN CampaignParks cp on sc.CampaignID = cp.CampaignID
WHERE
((SELECT COUNT(*) FROM CampaignParks cp2 WHERE cp2.CampaignID = sc.CampaignID AND cp2.IncludeInCampaign = 1) > 0 OR cp.ParkID = #ParkID)
But, this isn't getting me the right results.
(I need to take my daughter to gymnastics... I'll take a look at relies when I get back. Thank you!!)

I think your code is close. The major difference is the AND versus OR in the WHERE clause:
SELECT sc.ContactID, cp.*
FROM Campaigns c JOIN
CampaignParks cp
on sc.CampaignID = cp.CampaignID
WHERE cp.ParkId = #ParkId AND
EXISTS (SELECT 1
FROM CampaignParks cp2
WHERE cp2.CampaignID = cp.CampaignID AND
cp2.IncludeInCampaign = 1
);

Related

I have info on cycle counts in a warehouse that count the same locations multiple times. I want to get the latest NET_VAR for a specific location

I have used MAX(Date) and that will get me what i need until i put the qty in the mix, since they get different results after they fix things it has multiple answers and makes me group by the qty which in the end gives me multiple results. i just want the last count numbers.
SELECT (CH.MOD_DATE_TIME),LH.LOCN_BRCD ,DSP_SKU, (CH.ACTL_INVN_QTY-CH.EXPTD_QTY) "NET VAR" FROM CYCLE_COUNT_HIST CH , LOCN_HDR LH, ITEM_MASTER IM WHERE CH.WHSE = 'SH1' AND CH.LOCN_ID = LH.LOCN_ID AND CH.SKU_ID = IM.SKU_ID AND IM.CD_MASTER_ID = '147001' and DSP_SKU LIKE 'JBLBAR31BLKAM' AND LH.LOCN_BRCD = 'HAHK42A01' AND trunc(CH.CREATE_DATE_TIME) > SYSDATE-120
It returns 3 rows of results and I want the most recent line only. I plan to modify this to (select dsp_sku, sum(NET_VAR) in the end to run a summary of the sku.
I think you can use subquery.
You just need to put the following condition in where clause:
where .....
AND
CH.MOD_DATE_TIME = (select MAX( MOD_DATE_TIME)
from cycle_count_hist)

Update field where the items are part of a subquery

I am testing some software and need to make some adjustments to the fields manually. For all items that are produced at factory A, the lead time needs to be adjusted for the other factories those items are produced. However, the other items that are at the other factories need the normal leadtime.
I have the query to select the items that are produced at the alternate factories. I've tried using update where exists and having that be a subquery. I can't seem to get it to work as I feel it should
update newgdmoperation
set newgdmoperation.productionoffset = 75
where exists
(
select
newgdmoperation.operationid
from newgdmoperation
right join
(
select mainproductid,productionoffset
from newgdmoperation
where fromlocationid = 'KR'
and transporttype like 'Ves%'
) a
on newgdmoperation.mainproductid = a.mainproductid
where fromlocationid <> 'KR'
and transporttype like 'Ves%'
)
This doesn't give any error results. However, it updates the field for all item.
The subquery under the where clause does in fact return the operationid (unique id) for the items that need to be updated. I was expecting that with the where exists, that only the items in the subquery would be updated while the rest would be left untouched.
Assuming that you're trying to update the NEWGDMOPERATION table it looks to me like you should use IN rather than EXISTS, and so your statement should be
UPDATE NEWGDMOPERATION g
SET g.PRODUCTIONOFFSET = 75
WHERE g.OPERATIONID IN (SELECT g2.OPERATIONID
FROM NEWGDMOPERATION g2
RIGHT JOIN (SELECT g3.MAINPRODUCTID,
g3.PRODUCTIONOFFSET
FROM NEWGDMOPERATION g3
WHERE g3.FROMLOCATIONID = 'KR' AND
g3.TRANSPORTTYPE LIKE 'VES%') a
ON g2.MAINPRODUCTID = a.MAINPRODUCTID
WHERE g2.FROMLOCATIONID <> 'KR' AND
g2.TRANSPORTTYPE LIKE 'VES%')

SQL Server - Need to SUM values in across multiple returned records

In the following query I am trying to get TotalQty to SUM across both the locations for item 6112040, but so far I have been unable to make this happen. I do need to keep both lines for 6112040 separate in order to capture the different location.
This query feeds into a Jasper ireport using something called Java.Groovy. Despite this, none of the PDFs printed yet have been either stylish or stained brown. Perhaps someone could address that issue as well, but this SUM issue takes priority
I know Gordon Linoff will get on in about an hour so maybe he can help.
DECLARE #receipt INT
SET #receipt = 20
SELECT
ent.WarehouseSku AS WarehouseSku,
ent.PalletId AS [ReceivedPallet],
ISNULL(inv.LocationName,'') AS [ActualLoc],
SUM(ISNULL(inv.Qty,0)) AS [LocationQty],
SUM(ISNULL(inv.Qty,0)) AS [TotalQty],
MAX(CAST(ent.ReceiptLineNumber AS INT)) AS [LineNumber],
MAX(ent.WarehouseLotReference) AS [WarehouseLot],
LEFT(SUM(ent.WeightExpected),7) AS [GrossWeight],
LEFT(SUM(inv.[Weight]),7) AS [NetWeight]
FROM WarehouseReceiptDetail AS det
INNER JOIN WarehouseReceiptDetailEntry AS ent
ON det.ReceiptNumber = ent.ReceiptNumber
AND det.FacilityName = ent.FacilityName
AND det.WarehouseName = ent.WarehouseName
AND det.ReceiptLineNumber = ent.ReceiptLineNumber
LEFT OUTER JOIN Inventory AS inv
ON inv.WarehouseName = det.WarehouseName
AND inv.FacilityName = det.FacilityName
AND inv.WarehouseSku = det.WarehouseSku
AND inv.CustomerLotReference = ent.CustomerLotReference
AND inv.LotReferenceOne = det.ReceiptNumber
AND ISNULL(ent.CaseId,'') = ISNULL(inv.CaseId,'')
WHERE
det.WarehouseName = $Warehouse
AND det.FacilityName = $Facility
AND det.ReceiptNumber = #receipt
GROUP BY
ent.PalletId
, ent.WarehouseSku
, inv.LocationName
, inv.Qty
, inv.LotReferenceOne
ORDER BY ent.WarehouseSku
The lines I need partially coalesced are 4 and 5 in the above return.
Create a second dataset with a subquery and join to that subquery - you can extrapolate from the following to apply to your situation:
First the Subquery:
SELECT
WarehouseSku,
SUM(Qty)
FROM
Inventory
GROUP BY
WarehouseSku
Now apply to your query - insert into the FROM clause:
...
LEFT JOIN (
SELECT
WarehouseSKU,
SUM(Qty)
FROM
Inventory
GROUP BY
WarehouseSKU
) AS TotalQty
ON Warehouse.WarehouseSku = TotalQty.WarehouseSku
Without seeing the actual schema DDL it is hard to know the exact cardinality, but I think this will point you in the right direction.

Issue with my Left outer join query

Here are my tables,
I'm trying to fetch the list of free bets with the details if the user has placed his bet or not. This is the query i have written to fetch the details for the same,
select DISTINCT tbl_CreateFreeBet.FreeBetID,
tbl_CreateFreeBet.FreeBetDescription,
tbl_CreateFreeBet.FreeBetAmount,
tbl_CreateFreeBet.TournamentID,
tbl_CreateFreeBet.MatchID,
tbl_UserFreeBets.UserForYes,
tbl_UserFreeBets.UserForNo,
tbl_UserFreeBets.UserForNoBets
from tbl_CreateFreeBet left outer join tbl_UserFreeBets
on tbl_CreateFreeBet.MatchID = 1 and
tbl_CreateFreeBet.MatchID = tbl_UserFreeBets.MatchID and
tbl_CreateFreeBet.FreeBetID = tbl_UserFreeBets.FreeBetID and
tbl_CreateFreeBet.TournamentID = tbl_UserFreeBets.TournamentID and
(tbl_UserFreeBets.UserForYes = 'User2' or tbl_UserFreeBets.UserForNo =
'User2')
This is working fine, when there is a data in tbl_CreateFreeBet table for the MatchID. But if there is no data, then this query is not returning the expected result.
For example: With tbl_CreateFreeBet.MatchID = 1, I need to get all the free bets of matchID = 1, with the details of the passed in user, if has bet on 'yes' or 'no'. This comes up fine, as there is data for MatchId = 1 in tbl_CreateFreeBet.
But, it fails, when the tbl_CreateFreeBet.MatchID = 2 input is passed. Here there is no free bet created for the MatchID = 2. But still it returns me the result for MatchID=1.
Please share the query if one is aware of what changes need to be done for my query. Thank you.
Conditions on the first table in a LEFT JOIN should be in the WHERE clause. I think you intend this logic:
select cfb.FreeBetID, cfb.FreeBetDescription, cfb.FreeBetAmount,
cfb.TournamentID, cfb.MatchID,
ufb.UserForYes, ufb.UserForNo, ufb.UserForNoBets
from tbl_CreateFreeBet cfb left outer join
tbl_UserFreeBets ufb
on cfb.MatchID = ufb.MatchID and
cfb.FreeBetID = ufb.FreeBetID and
cfb.TournamentID = ufb.TournamentID and
(ufb.UserForYes = 'User2' or ufb.UserForNo = 'User2')
where cfb.MatchId = 1

sql join -vs- where clause not producing the same result?

I am a bit boggled as to why these two SQL constructs do not yield the same result.
SQL#1 return 2 identical records (dups) when only one exists in the defects table... see next sql
SELECT *
FROM Defects d
JOIN StatusCode C ON C.CodeName = d.Status AND c.scid = 10
WHERE d.AssignedTo='me'
SQL#2 reruns 1 record - this is correct cause lookign at raw data there is one defect not closed for 'me'
SELECT *
FROM Defects d
WHERE d.AssignedTo='me' AND Status <> 'closed'
all i am doing is instead of using a negative where status not in something , using a positive by way of the join to records that have every value defect status other than closed
why does this happen, and how can i alter my select with the join to corect its result. i tried using DISTINCT but it fails with:
The ntext data type cannot be selected
as DISTINCT because it is not
comparable.
there are no status codes that are 'closed', not a single one:
select * from StatusCode where scid = 10
results in these values:
Fixed
New
Ready for Retest
Failed Retest
Quality Follow Up
Reopen
Rejected
Consumer
In Coding
Open
Fixed
New
Ready for Retest
Failed Retest
Quality Follow Up
Reopen
Rejected
Consumer
In Coding
Open
The inner join will return all matching combinations of rows, so there must be two rows in the StatusCode table that match the "Status" value of your Defect (and have scid = 10).
FixedNewReady for RetestFailed RetestQuality Follow UpReopenRejected ConsumerIn CodingOpenFixedNewReady for RetestFailed RetestQuality Follow UpReopenRejected ConsumerIn CodingOpen
Not sure if I parsed your list exactly right, but there do appear to be duplicates. The answer, then, is to either eliminate the duplicates in the StatusCode table, or apply an additional filter to distinguish between them if the duplicates are valid.
How many rows are returned by this?
SELECT * FROM StatusCode C WHERE c.scid = 10
You may therefore want to do this:
SELECT *
FROM Defects d
WHERE d.AssignedTo='me' AND d.Status IN (
SELECT C.CodeName FROM StatusCode C WHERE C.scid = 10
)
Edit to address your edit: since you have multiple states with scid=10, each of those will be joined to your rows, which is why you get the duplicates. My code suggestion is still valid though.
I would think the problem is here:
JOIN StatusCode C ON C.CodeName = d.Status AND c.scid = 10
The c.scid = 10 should be in the where clause.