SQL: Variable to update a set of items - sql

SO, each item has an id, a setId, and a name.
Current data may only have one NAME field filled out in an entire set.
EX>
>ID = 1 >NAME = 'Bob' >SETID = 5
>ID = 2 >NAME = NULL >SETID = 5
>ID = 3 >NAME = NULL >SETID = 5
>ID = 4 >NAME = NULL >SETID = 5
I am looking for an SQL script that GET the one record that is not null in a "SET"
SET the remaining items in the "SET" for that "NAME" record.
The end result I am aiming for would look like this:
>ID = 1 >NAME = 'Bob' >SETID = 5
>ID = 2 >NAME = 'Bob' >SETID = 5
>ID = 3 >NAME = 'Bob' >SETID = 5
>ID = 4 >NAME = 'Bob' >SETID = 5

Assuming there is only one Name in a set that is not null, you could use a CTE and do something like:
;WITH NameHelper AS
(
SELECT
Name,
SetID
FROM MyTable
WHERE Name IS NOT NULL
GROUP BY Name, SetID
)
UPDATE MyTable SET Name = NameHelper.Name
FROM MyTable
INNER JOIN NameHelper ON MyTable.SetID = NameHelper.SetID

Related

Select cases from long table by key variable grouping

I have a table like below:
caseid | ncode | code | test
1 1 ABC TRUE
1 2 DEF TRUE
2 1 ABC TRUE
3 1 DEF TRUE
3 2 HIJ FALSE
Where caseid represents an individual case. This table creates the relationship that each individual case can have multiple codes associated with it (ncode and code). test is just a variable that tracks a boolean value of interest.
I have specific requirements for my query:
I need all cases where code = ABC and ncode = 1 and test = TRUE. This criteria has the highest priority.
Of those cases from #1, I need to create an additional column called hasdef that is a boolean that indicates if that specific caseid has any other rows where code = DEF and test = TRUE. It should be TRUE if so, otherwise FALSE.
So from the above table, what should return is:
caseid | ncode | code | test | hasdef
1 1 ABC TRUE TRUE
2 1 ABC TRUE FALSE
caseid = 1 returns because code = ABC, ncode = 1, and test = TRUE. hasdef = TRUE because in the second row, caseid = 1, code = DEF and test = TRUE.
caseid = 2 returns because code = ABC, ncode = 1, and test = TRUE. hasdef = FALSE because there is no other row with caseid = 2 where code = DEF.
caseid = 3 does not return. Even though there is a row where code = DEF and test = TRUE, the first criteria (code = ABC and ncode = 1) is not first satisfied.
This is what I have so far, but I am not confident it is working as desired:
select tab1.*, tab2.code is not null as hasdef from
(select * from mytable
where code = 'ABC' and ncode = 1) as tab1
left join (
select caseid, any_value(code) code, any_value(test) test
from mytable
group by caseid
having code = 'DEF' and test is true
) as tab2
using(caseid)
order by caseid
Below is for BigQuery Standard SQL
#standardSQL
select * from (
select *,
0 < countif(code = 'DEF' and test is true) over(partition by caseid) as hasdef
from `project.dataset.table`
)
where code = 'ABC' and ncode = 1 and test is true
if to apply to sample data from your question - output is
Note: you can replace test is true with just test as in below
select * from (
select *,
0 < countif(code = 'DEF' and test) over(partition by caseid) as hasdef
from `project.dataset.table`
)
where code = 'ABC' and ncode = 1 and test

Filter only get one condition

I have a validation in WHERE clause like:
...
AND (#BDOnly = 0
OR [DT].[Abbreviation] = #IsBDChecked)
AND (#CDOnly = 0
OR [DT].[Abbreviation] = #IsCDChecked)
AND (#PPOOnly = 0
OR [DT].[Abbreviation] = #IsPPOChecked)
AND (#FBOMOnly = 0
OR [DT].[Abbreviation] = #IsFBOMChecked)
AND (#APOnly = 0
OR [DT].[Abbreviation] = #IsAPChecked)
AND (#COOnly = 0
OR [DT].[Abbreviation] = #IsCOChecked)
So each AND clause check if boolean is bit value is 0 or 1, if it's 0 just do any but if it's 1 it do a filter. My problem is
if I'm sending two with value 1, I mean
#BDOnly = 1 and #CDOnly = 1 it only filter one of them instead get two filters I mean:
[DT].[Abbreviation] = #IsBDChecked
and
[DT].[Abbreviation] = #IsCDChecked
What am I doing wrong? Regards
I'm going to take a guess here because there's not enough data. If you want to return a row where Abbreviation matched #IsBDChecked only when #BDOnly is set, and also another row where Abbreviation matches #IsCDChecked when #CDOnly is set, try this:
(#BDOnly = 1
AND [DT].[Abbreviation] = #IsBDChecked)
OR (#CDOnly = 1
AND [DT].[Abbreviation] = #IsCDChecked)
OR (#PPOOnly = 1
AND [DT].[Abbreviation] = #IsPPOChecked)
OR (#FBOMOnly = 1
AND [DT].[Abbreviation] = #IsFBOMChecked)
OR (#APOnly = 1
AND [DT].[Abbreviation] = #IsAPChecked)
OR (#COOnly = 1
AND [DT].[Abbreviation] = #IsCOChecked)
Small representative case:
DECLARE #ADOnly BIT = 0
, #BDOnly BIT = 1
, #CDOnly BIT = 1
, #IsADChecked NVARCHAR(100) = 'A'
, #IsCDChecked NVARCHAR(100) = 'C'
, #IsBDChecked NVARCHAR(100) = 'B'
;WITH myTable AS
(
SELECT * FROM (VALUES ('A'), ('B'), ('C')) X(Abbreviation)
)
SELECT *
FROM myTable
WHERE (#ADOnly = 1 AND Abbreviation = #IsADChecked)
OR (#BDOnly = 1 AND Abbreviation = #IsBDChecked)
OR (#CDOnly = 1 AND Abbreviation = #IsCDChecked)
Yields:
Abbreviation
------------
B
C

sql how to add inner join and multiple conditions to filter

I have this query
SELECT DISTINCT IP.IRId
FROM cmp.NPTable NP
INNER JOIN IPTable IP ON IP.IPtId = NP.IPd
LEFT JOIN IPCTable IPC ON IPC.IPId = NP.IPId
WHERE NP.PCN Id = #PCNId
AND (IP.IsCompliant = 1 AND IPC.CheckId = 1) OR (IP.IsCompliant = 0 AND IPC.CheckId = 1)
This is not working correcty
THe IPTable either has IsCompliant = null, 0 or 1 -- this is basically to indicate true or false
IPC.CheckId is either 1 or 2 -- this is the primary ID in this table
The only match integer match is the value 1 between the two tables.
I only want to bring back rows if IsCompliant = 1 and CheckId = 1
else if IsCompliant is null or 0, then CheckId = 2.
The clause I added to my where which is
AND (IP.IsCompliant = 1 AND IPC.CheckId = 1) OR (IP.IsCompliant = 0 AND IPC.CheckId = 1)
This does not work. Help. Will be very appreciated.
Thanks
WHERE NP.PCN Id = #PCNId
AND
(
(IP.IsCompliant = 1 AND IPC.CheckId = 1) OR
((IP.IsCompliant is null or IP.IsCompliant = 0) AND IPC.CheckId = 2)
)

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

This is the failed query.
Failed SQL:
Select SO_DOC_CD,
SO_DOC_DEPT_CD,
SO_DOC_ID,
SO_DOC_VERS_NO,
SR_DOC_CD,
SR_DOC_DEPT_CD,
SR_DOC_ID,
SR_DOC_VERS_NO,
DOC_LAST_DT,
DOC_PHASE_CD,
DOC_PHASE_CD_SO,
DOC_STA_CD,
VEND_CUST_CD,
DOC_SH_DSCR,
RESP_STA,
RESP_TM_WEB,
"Created By",
QRY_SRCH_STRING,
SO_DOC_REF,
SR_DOC_REF,
SO_DOC_FUNC_CD,
RESP_DT_ADV,
SO_SR_QRY.RESP_STA_ORD,
APPL_STA_CD,
SO_SR_QRY.APPL_STA_CD_ORD,
SO_SR_QRY.AWD_FL
From (
Select SO_DOC_HDR.DOC_CD As SO_DOC_CD,
SO_DOC_HDR.DOC_DEPT_CD As SO_DOC_DEPT_CD,
SO_DOC_HDR.DOC_ID As SO_DOC_ID,
SO_DOC_HDR.DOC_VERS_NO As SO_DOC_VERS_NO,
SO_DOC_HDR.SO_CLSNG_DT As SO_CLSNG_DT,
SO_DOC_HDR.SO_CLSNG_TM As SO_CLSNG_TM,
SR_DOC_HDR.DOC_CD As SR_DOC_CD,
SR_DOC_HDR.DOC_DEPT_CD As SR_DOC_DEPT_CD,
SR_DOC_HDR.DOC_ID As SR_DOC_ID,
SR_DOC_HDR.DOC_VERS_NO As SR_DOC_VERS_NO,
SR_DOC_HDR.DOC_LAST_DT As DOC_LAST_DT,
SR_DOC_HDR.DOC_PHASE_CD As DOC_PHASE_CD,
SR_DOC_HDR.APPL_STA_CD As APPL_STA_CD,
SO_DOC_HDR.DOC_PHASE_CD As DOC_PHASE_CD_SO,
SR_DOC_HDR.DOC_STA_CD As DOC_STA_CD,
SR_DOC_HDR.VEND_CUST_CD As VEND_CUST_CD,
SO_DOC_HDR.DOC_SH_DSCR As DOC_SH_DSCR,
SR_DOC_HDR.RESP_STA As RESP_STA,
SR_DOC_HDR.RESP_TM_WEB As RESP_TM_WEB,
SR_DOC_HDR.DOC_CREA_USID As "Created By",
SR_DOC_HDR.QRY_SRCH_STRING As QRY_SRCH_STRING,
SO_DOC_HDR.DOC_REF As SO_DOC_REF,
SR_DOC_HDR.DOC_REF As SR_DOC_REF,
SO_DOC_HDR.DOC_FUNC_CD As SO_DOC_FUNC_CD,
SR_DOC_HDR.RESP_DT_ADV As RESP_DT_ADV,
Case When RESP_STA = 7 Then 1
When RESP_STA = 1 Then 2
When RESP_STA = 2 Then 4
When RESP_STA = 3 Then 3
When RESP_STA = 4 Then 5
When RESP_STA = 5 Then 6
End As RESP_STA_ORD,
Case When APPL_STA_CD = 5 Then 1
When APPL_STA_CD = 4 Then 2
When APPL_STA_CD = 1 Then 3
When APPL_STA_CD = 3 Then 4
When APPL_STA_CD = 6 Then 5
When APPL_STA_CD = 2 Then 6
When APPL_STA_CD = 7 Then 7
End As APPL_STA_CD_ORD,
Case When Exists (
Select 1
From SR_DOC_COMMLN
Where SR_DOC_COMMLN.SO_DOC_ID = SR_DOC_HDR.SO_DOC_ID
And SR_DOC_COMMLN.SO_DOC_DEPT_CD = SR_DOC_HDR.SO_DOC_DEPT_CD
And SR_DOC_COMMLN.SO_DOC_VERS_NO = SR_DOC_HDR.SO_DOC_VERS_NO
And SR_DOC_COMMLN.SO_DOC_CD = SR_DOC_HDR.SO_DOC_CD
And (
SR_DOC_COMMLN.AWARD_CREATED = 1
Or SR_DOC_COMMLN.AWARD_FINALIZED = 1
)
) Then 1
Else 0
End As AWD_FL
From av3112jm1.dbo.SR_DOC_HDR SR_DOC_HDR,
av3112jm1.dbo.SO_DOC_HDR SO_DOC_HDR
Where SO_DOC_HDR.DOC_CD = SR_DOC_HDR.SO_DOC_CD
And SO_DOC_HDR.DOC_DEPT_CD = SR_DOC_HDR.SO_DOC_DEPT_CD
And SO_DOC_HDR.DOC_ID = SR_DOC_HDR.SO_DOC_ID
And SO_DOC_HDR.DOC_PHASE_CD = 3
) SO_SR_QRY
Where 1 = 1
And (
SR_DOC_HDR.DOC_VERS_NO = 1
And SR_DOC_HDR.DOC_DEPT_CD = '010'
And SR_DOC_HDR.DOC_CD = 'GFA'
And SR_DOC_HDR.DOC_ID = 'ESR09141700000000002'
)
Order By Case When SO_DOC_FUNC_CD = 3 Then 4
When SO_SR_QRY.AWD_FL = 1 Then 2
When Convert(DateTime, SO_CLSNG_DT, (108)) + Convert(DateTime, SO_CLSNG_TM, 114) <= '2017-09-20 02:44:23' Then 3
Else 1
End Asc,
SO_CLSNG_DT Desc,
SO_CLSNG_TM Desc;
The problem is that in your outer query, you're referencing SR_DOC_HDR.DOC_VERS_NO = 1, but your inner query has that column aliased as SR_DOC_VERS_NO.
You need to use the aliases given in the inner query.
Change your outer WHERE statement to:
Where 1 = 1
And (
SR_DOC_VERS_NO = 1
And SR_DOC_DEPT_CD = '010'
And SR_DOC_CD = 'GFA'
And SR_DOC_ID = 'ESR09141700000000002'
)
in your subquery you use twice the alias
sr_doc_hdr.doc_vers_no AS SR_DOC_VERS_NO

Update a table from another table

I have got 2 tables "animal_breeds" and "ztmp.ztmp_509810_anims_out". In "animals breed" every animal has key and breed name and percentage. Few animals might have 2 different breeds with different percentage. Now based on the animals key in "animals_breeds" i want to update "ztmp.ztmp_509810_anims_out"
i am using this code which i know is wrong
update ztmp.ztmp_509810_anims_out
set
alt_id1 = ab.breed
,alt_id2 = pcnt
,alt_id3 = ab.breed
,alt_id4 = pcnt
,alt_id5 = ab.breed
,alt_id6 = pcnt
,alt_id7 = ab.breed
,alt_id8 = pcnt
from animal_breeds ab
where ab.soc_code = ztmp_509810_anims_out.soc_code and ab.animals_key = ztmp_509810_anims_out.animals_key
and ab.soc_code = 'AUNDB';
could i use a for loop inside an update statement?
UPDATE ztmp.ztmp_509810_anims_out AS z
SET soc_code = q.soc_code,
animals_key = q.animals_key,
alt_id1 = breeds[1],
alt_id2 = pcnts[1],
alt_id3 = breeds[2],
alt_id4 = pcnts[2]
FROM (SELECT soc_code, animals_key,
array_agg(breed) breeds, array_agg(pcnt) pcnts
FROM animal_breeds
GROUP BY soc_code, animals_key
) q
WHERE z.soc_code = q.soc_code
AND z.animals_key = q.animals_key;
If there can be more than 2 breeds per animals_key, add breeds[3] and pcnts[3] and so on.