I want to create a new column where If my Rom Indicator is 'Y', then pick the Account ID value and swap it for all the IDs as shown below
I tried using Case statments like this
CASE WHEN PRIM_IND = 'Y' THEN ACT_ID ELSE ACT_ID END
select t.*
,max(case when PRI_IND = 'Y' then ACT_ID end) over(partition by ID) as ACT_ID_NEW
from t
ID
ACT_ID
PRI_IND
ACT_ID_NEW
200
ACT01
N
ACT02
200
ACT02
Y
ACT02
201
ACT03
Y
ACT03
201
ACT04
N
ACT03
201
ACT05
N
ACT03
202
ACT06
Y
ACT06
Fiddle
Not sure if this is what you wanted, but the output matches so I guess so. It's just a basic self INNER JOIN where you only want to join on the records with pri_ind = 'Y'
SELECT a.id,
a.act_id,
a.pri_ind,
b.act_id AS act_id_new
FROM tab1 a
INNER JOIN tab1 b
ON a.id = b.id
AND b.pri_ind = 'Y'
Related
I have three ORACLE SQL tables where I have to query DATA_TABLE and pull dataid's whose attr is 2000 and value is cat and also the value for attr = 2001 has to be available in NAME_TABLE oldname column and I have to display Name from DOC_TABLE(using dataid's we got from above) and Code from Name_Table
From the above table my output has to be
Name,Code
FirstName, DG
Because dataid 1 in DATA_TABLE for attr 2000 its value is Cat and for attr 2001 its value is dog which is available in NAME_TABLE oldname column, As Name where dataid=1 in DOC_TABLE is FirstName and code for dog in NAME_TABLE is DG
I would phrase your query as follows:
select do.name, na.code
-- start the join here
from doc_table do
-- pull dataid's from DATA_TABLE whose attr is 2000 and value is cat
inner join data_table da on da.dataid = do.dataid and da.attr = 2000 and da.value = 'cat'
-- pull code from NAME_TABLE
inner join name_table na on na.oldname = da.value
-- the value for attr = 2001 has to be available in NAME_TABLE
where exists(
select 1
from data_table da1
inner join name_table na1 on na1.oldname = da1.value
where da1.dataid = do.dataid and da1.attr = 2001
)
You can use analytical function as following:
Select distinct name, code from
(select do.name, na.code,
Count(case when da.value='cat' and da.attr=2000 then 1 end)
Over (Partition by do.dataid) as cat_cnt,
Count(case when na.code is not null and da.attr=2001 then 1 end)
Over (Partition by do.dataid) as code_cnt
from doc_table do
Left join data_table da on da.dataid = do.dataid
Left join name_table na on na.oldname = da.value)
Where cat_cnt > 0 and code_count > 0;
Cheers!!
Going to use this query as a subquery, the problem is it returns many rows of duplicates. Tried to use COUNT() instead of exists, but it still returns a multiple answer.
Every table can only contain one record of superRef.
The below query I`ll use in SELECT col_a, [the CASE] From MyTable
SELECT CASE
WHEN
EXISTS (SELECT 1 FROM A WHERE
A_superRef = myTable.sysno AND A_specAttr = 'value')
THEN 3
WHEN EXISTS (SELECT 1 FROM B
INNER JOIN С ON С_ReferenceForB = B_sysNo WHERE C_superRef = myTable.sysno AND b_type = 2)
THEN 2
ELSE (SELECT C_intType FROM C
WHERE C_superRef = myTable.sysno)
END
FROM A, B, C
result:
3
3
3
3
3
3...
What if you did this? Because Im guessing you are getting an implicit full outer join A X B X C then running the case statement for each row in that result set.
SELECT CASE
WHEN
EXISTS (SELECT 1 FROM A WHERE
A_superRef = 1000001838012)
THEN 3
WHEN EXISTS (SELECT 1 FROM B
INNER JOIN С ON С_ReferenceForB = B_sysNo AND C_superRef = 1000001838012 )
THEN 2
ELSE (SELECT C_type FROM C
WHERE C_superRef = 1000001838012)
END
FROM ( SELECT COUNT(*) FROM A ) --This is a hack but should work in ANSI sql.
--Your milage my vary with different RDBMS flavors.
DUAL is what I needed, thanks to Thorsten Kettner
SELECT CASE
WHEN
EXISTS (SELECT 1 FROM A WHERE
A_superRef = 1000001838012)
THEN 3
WHEN EXISTS (SELECT 1 FROM B
INNER JOIN С ON С_ReferenceForB = B_sysNo AND C_superRef = 1000001838012 )
THEN 2
ELSE (SELECT C_type FROM C
WHERE C_superRef = 1000001838012)
END
FROM DUAL
I have this table:
Table_NAME_A:
quotid itration QStatus
--------------------------------
5329 1 Assigned
5329 2 Inreview
5329 3 sold
4329 1 sold
4329 2 sold
3214 1 assigned
3214 2 Inreview
Result output should look like this:
quotid itration QStatus
------------------------------
5329 3 sold
4329 2 sold
3214 2 Inreview
T-SQL query, so basically I want the data within "sold" status if not there then "inreview" if not there then "assigned" and also at the same time if "sold" or "inreview" or "assigned" has multiple iteration then i want the highest "iteration".
Please help me, thanks in advance :)
This is a prioritization query. One way to do this is with successive comparisons in a union all:
select a.*
from table_a a
where quote_status = 'sold'
union all
select a.*
from table_a a
where quote_status = 'Inreview' and
not exists (select 1 from table_a a2 where a2.quoteid = a.quoteid and a2.quotestatus = 'sold')
union all
select a.*
from table_a a
where quote_status = 'assigned' and
not exists (select 1
from table_a a2
where a2.quoteid = a.quoteid and a2.quotestatus in ('sold', 'Inreview')
);
For performance on a larger set of data, you would want an index on table_a(quoteid, quotestatus).
You want neither cursors nor if/then for this. Instead, you'll use a series of self-joins to get these results. I'll also use a CTE to simplify getting the max iteration at each step:
with StatusIterations As
(
SELECT quotID, MAX(itration) Iteration, QStatus
FROM table_NAME_A
GROUP BY quotID, QStats
)
select q.quotID, coalesce(sold.Iteration,rev.Iteration,asngd.Iteration) Iteration,
coalesce(sold.QStatus, rev.QStatus, asngd.QStatus) QStatus
from
--initial pass for list of quotes, to ensure every quote is included in the results
(select distinct quotID from table_NAME_A) q
--one additional pass for each possible status
left join StatusIterations sold on sold.quotID = q.quotID and sold.QStatus = 'sold'
left join StatusIterations rev on rev.quotID = q.quotID and rev.QStatus = 'Inreview'
left join StatusIterations asngd on asngd.quotID = q.quotID and asngd.QStatus = 'assigned'
If you have a table that equates a status with a numeric value, you can further improve on this:
Table: Status
QStatus Sequence
'Sold' 3
'Inreview' 2
'Assigned' 1
And the code becomes:
select t.quotID, MAX(t.itration) itration, t.QStatus
from
(
select t.quotID, MAX(s.Sequence) As Sequence
from table_NAME_A t
inner join Status s on s.QStatus = t.QStatus
group by t.quotID
) seq
inner join Status s on s.Sequence = seq.Sequence
inner join table_NAME_A t on t.quotID = seq.quotID and t.QStatus = s.QStatus
group by t.quoteID, t.QStatus
The above may look like complicated at first, but it can be faster and it will scale easily beyond three statuses without changing the code.
I have the following table:
ID Number Revision
x y 0
x y 1
z w 0
a w 0
a w 1
b m 0
b m 0
I need to return rows that for the same Number thare are more then one ID with the same Revision.Number can be "Null" and I don't need those values.
The output should be:
z w 0
a w 0
I have tried the following query:
SELECT a.id,a.number,a.revision,
FROM table a INNER JOIN
(SELECT id, number, revision FROM table where number > '0'
GROUP BY number HAVING COUNT(*) > 1
) b ON a.revision = b.revision AND a.id != b.id
A little addition- I have rows in my table with the same Number, ID and Revision- I don't need those rows in my query to be displayed!
It is not working! Please help me to figure out how to fix it.
Thanks.
Select t.Id,s.number,t.revision
from (Select number,count(*) 'c'
from table t1
where revision=0
group by number
having count(*) > 1
) s join table t on t.number= s.number
where revision = 0
Another simple approach:
SELECT DISTINCT b.id, b.Number, b.Revision
FROM tbl a
INNER JOIN tbl b
ON a.ID != b.ID AND a.Number = b.Number AND a.Revision = b.Revision;
This is tested in MySql 5, syntax might differ slightly.
You are not that far away with your query:
SELECT a.id,a.number,a.revision
FROM table a
JOIN (
-- multiple id for the same number and revision
SELECT number, revision
FROM table
GROUP BY number, revision
HAVING COUNT(*) > 1
) b
ON a.revision = b.revision
AND a.number = b.number
Untested, but you should get the idea. If your sql-server is a resent version you can solve this with OLAP functions as well.
To filter out rows where the whole row is duplicated we can select only unique rows via group by and having:
SELECT a.id,a.number,a.revision
FROM table a
JOIN (
-- multiple id for the same number and revision
SELECT number, revision
FROM table
GROUP BY number, revision
HAVING COUNT(*) > 1
) b
ON a.revision = b.revision
AND a.number = b.number
GROUP BY a.id,a.number,a.revision
HAVING COUNT(1) = 1
In Oracle how do I find Cars which must have Feature1 and have at lest, one out of Feature2 or Feature3. Sample table and expected result should look like below screenshot. Thanks Kiran
This should work:
select t1.car, t1.feature
from yourtable t1
inner join
( -- inner select returns the cars with the Feature1 and Feature2 or Feature3
select car, feature
from yourtable
where feature = 'Feature1'
and exists (select car
from yourtable
where feature in ('Feature2', 'Feature3'))
) t2
on t1.car = t2.car
where t1.feature in ('Feature1', 'Feature2', 'Feature3') -- this excludes any other features
see SQL Fiddle with Demo
I like to do this with GROUP BY and HAVING:
select car
from t
group by car
having max(case when feature = 'Feature1' then 1 else 0 end) = 1 and
max(case when feature in ('Feature1', 'Feature2') then 1 else 0 end) = 1
This query returns the cars. To get the featuers as well, you have to join tis back in:
select t.*
from (select car
from t
group by car
having max(case when feature = 'Feature1' then 1 else 0 end) = 1 and
max(case when feature in ('Feature1', 'Feature2') then 1 else 0 end) = 1
) c join
t
on t.car = c.car
I like this method, because the same idea can be used for handling many different similar queries -- AND conditions, OR conditions, different subgroups, and different counts.