Find the Row which contain only row with zero and One for the Particular data - sql

I have data where group will one row as zero and one and for the same data value will give one and two.
I have tried with below code .which seems to be not working
select *
from (select livecasnum, flag,
DENSE_RANK()over (partition by livecasnum order by flag) as Ranks
from TblcaseFlag
group by livecasnum, flag
) b
group by livecasnum,flag,Ranks
having count(flag + Ranks) = 1 and flag <> 1
I need only like data one row which having only zero and one ex: 99149

Why not use not exists instead :
select tf.*
from TblcaseFlag tf
where tf.flag = 0 and
not exists (select 1
from TblcaseFlag tf1
where tf.livecasnum = tf1.livecasnum and
tf1.flag = 1
);

Related

SQL Select row depending on values in different columns

I've already found so many answers here but now I can't seem to find any to my specific problem.
I can't figure out how to select a value from a row depending on the value in different columns
with the below table, I want to achieve the following results.
in case the value in column stdvpuni = 1 then return values / contents from this row for the article (column art).
in case the value in column stdvpuni = 0 then return values / contents from the row where STDUNIABG = 1 for this article (column art).
You seem to want one row part art, based on the content of other rows. That suggests using row_number():
select t.*
from (select t.*,
row_number() over (partition by art order by stdvpuni desc, STDUNIABG desc) as seqnum
from t
) t
where seqnum = 1;
You don't specify what to do if neither column is 1. You might want a where clause (where 1 in (stdvpuni, STDUNIABG)) or another condition in the order by.
I do not know what values / contents is, but I suppose that's easy for you to figure out. So, I will focus on the way to select this:
SELECT
CASE
WHEN current.stdvpuni = 1 THEN 'values / contents of current row'
ELSE 'values / contents of other row'
END
FROM yourtable current
JOIN yourtable other
ON other.stdvpuni = 1;
Use your conditions with NOT EXISTS in the WHERE clause:
SELECT t1.*
FROM tablename t1
WHERE t1.STDVPUNI = 1
OR (
t1.STDVPUNI = 0 AND t1.STDUNIABG = 1
AND NOT EXISTS (SELECT 1 FROM tablename t2 WHERE t2.ART = t1.ART AND t2.STDVPUNI = 1)
);

Finding rows in SQL where changes but only certain changes while keeping others

I have this scenario where I want each occurrence of an active row to bring back that row in my result set and also inactive if there is only 1 inactive record for that IDENTIFIER and also if there are more than 1 active also show those. I've used Row_Number function and then in another query show where the row = '1' but if I do that row 1s only come back and then I lose some of my desired results. To restate my issue is I want all active records to come back and only inactive where IDENTIFIER is unique. The row that is bold should not be shown in the results.
1 has 1 active record in the DB.
2 has 2 active and 1 inactive records.
3 has no active records.
4 has only 2 active records, no inactive.
You can use a windowed conditional count, this has the benfit of only scanning the table once
SELECT
t.IDENTIFIER,
t.DB_ID,
t.Status
FROM (
SELECT *,
HasActive = COUNT(CASE WHEN t.Status = 'Active' THEN 1 END) OVER (PARTITION BY t.IDENTIFIER)
FROM YourTable t
) t
WHERE t.Status = 'Active' OR t.HasActive = 0;
One way to do this is with NOT EXISTS:
SELECT t1.*
FROM tablename t1
WHERE t1.Status = 'Active'
OR NOT EXISTS (
SELECT 1
FROM tablename t2
WHERE t2.identifier = t1.identifier AND t2.db_id <> t1.db_id
);
I assume that the column db_id is unique, at least for the same identifier.
If I understood you correctly, this is my variant.
select IDENTIFIER, [DB_ID], [Status]
from Tab
where [Status]='Active'
union
select IDENTIFIER, [DB_ID], [Status]
from Tab as t
where [Status]='Inactive' And 1=(select Count(*) from Tab where
IDENTIFIER=t.IDENTIFIER)
Order by IDENTIFIER, [DB_ID]
you can do it like this, because (rank=1 and Status=Inactive) only if there are no active rows for a particular Identifier
select * from (
select *,
DENSE_RANK() OVER (PARTITION BY identifier order by status) AS rank
from some_table
)
where rank=1 or status = 'Active'

SQL: Update every entry with value from another entry that share same column value

I have the following table trn_ReceiptLog
I am wondering if it's possible to update amount of entry #1 to have same as entry #2 IF amount of entry #1 is 0?
I have over 5000 of these entries that need to be updated, basically something like:
UPDATE trn_ReceiptLog SET amount = (SELECT amount FROM trn_ReceiptLog WHERE receipt_type = 0) WHERE amount = 0
But I am not sure how to do it for all entries individually, do I need some sort of loop?
Condition 1: Receipt type will always be 0 of the one where amount needs to be taken from.
Condition 2: person_id will always be identical across two of these.
Condition 3 (Optional): Only perform this update IF there is only one receipt_type = 9 (Sometimes there might be 3 or 4 entries with same person_id and being receipt_type 9
You can use window functions to calculate the information needed for the conditions. Then the logic is simple:
with toupdate as (
select t.*,
max(case when receipt_type = 9 then amount else 0 end) over (partition by person_id) as amount_9,
sum(case when receipt_type = 9 then 1 else 0 end) over (partition by person_id) as num_9s
from t
)
update toupdate
set amount = amount_9
where receipt_type = 0;
With a self join:
update t
set t.amount = tt.amount
from trn_ReceiptLog t inner join trn_ReceiptLog tt
on tt.person_id = t.person_id
where t.receipt_type = 9 and tt.receipt_type = 0 and t.amount = 0
and not exists (
select 1 from trn_ReceiptLog
where entry_id <> t.entry_id and person_id = t.person_id and receipt_type = 9
)
The last part of the WHERE clause with AND NOT EXISTS... is the 3d optional condition.
See a simplified demo.

Create a new table with columns with case statements and max function

I have some problems in creating a new table from an old one with new columns defined by case statements.
I need to add to a new table three columns, where I compute the maximum based on different conditions. Specifically,
if time is between 1 and 3, I define a variable max_var_1_3 as max((-1)*var),
if time is between 1 and 6, I define a variable max_var_1_6 as max((-1)*var),
if time is between 1 and 12, I define a variable max_var_1_12 as max((-1)*var),
The max function needs to take the maximum value of the variable var in the window between 1 and 3, 1 and 6, 1 and 12 respectively.
I wrote this
create table new as(
select t1.*,
(case when time between 1 and 3 then MAX((-1)*var)
else var
end) as max_var_1_3,
(case when time between 1 and 6 then MAX((-1)*var)
else var
end) as max_var_1_6,
(case when time between 1 and 12 then MAX((-1)*var)
else var
end) as max_var_1_12
from old_table t1
group by time
) with data primary index time
but unfortunately it is not working. The old_table has already some columns, and I would like to import all of them and then compare the old table with the new one. I got an error that says that should be something between ) and ',', but I cannot understand what. I am using Teradata SQL.
Could you please help me?
Many thanks
The problem is that you have GROUP BY time in your query while trying to return all the other values with your SELECT t1.*. To make your query work as-is, you'd need to add each column from t1.* to your GROUP BY clause.
If you want to find the MAX value within the different time ranges AND also return all the rows, then you can use a window function. Something like this:
CREATE TABLE new AS (
SELECT
t1.*,
CASE
WHEN t1.time BETWEEN 1 AND 3 THEN (
MAX(CASE WHEN t1.time BETWEEN 1 AND 3 THEN (-1 * t1.var) ELSE NULL END) OVER()
)
ELSE t1.var
END AS max_var_1_3,
CASE
WHEN t1.time BETWEEN 1 AND 6 THEN (
MAX(CASE WHEN t1.time BETWEEN 1 AND 6 THEN (-1 * t1.var) ELSE NULL END) OVER()
)
ELSE t1.var
END AS max_var_1_6,
CASE
WHEN t1.time BETWEEN 1 AND 12 THEN (
MAX(CASE WHEN t1.time BETWEEN 1 AND 12 THEN (-1 * t1.var) ELSE NULL END) OVER()
)
ELSE t1.var
END AS max_var_1_12,
FROM old_table t1
) WITH DATA PRIMARY INDEX (time)
;
Here's the logic:
check if a row falls in the range
if it does, return the desired MAX value for rows in that range
otherwise, just return that given row's default value (var)
return all rows along with the three new columns
If you have performance issues, you could also move the max_var calculations to a CTE, since they only need to be calculated once. Also to avoid confusion, you may want to explicitly specify the values in your SELECT instead of using t1.*.
I don't have a TD system to test, but try it out and see if that works.
I cannot help with the CREATE TABLE AS, but the query you want is this:
SELECT
t.*,
(SELECT MAX(-1 * var) FROM old_table WHERE time BETWEEN 1 AND 3) AS max_var_1_3,
(SELECT MAX(-1 * var) FROM old_table WHERE time BETWEEN 1 AND 6) AS max_var_1_6,
(SELECT MAX(-1 * var) FROM old_table WHERE time BETWEEN 1 AND 12) AS max_var_1_12
FROM old_table t;

Get opposite of a query's results Access 2016

I'm trying to create an query that displays the opposite of another query (just like a boolean NOT).
This is the first query:
SELECT RoomNumber, StructureNumber
FROM TimeTables
WHERE HourNumber = 1 AND DayNumber = 1
I need to get all the rows that doesn't exists in that query's results.
At the first time I tried to subtract the full table from the first query but I could not do it because there is no "EXCEPT" in Access and
also because I need to subtract between four columns (there are two primary key columns in that table)
this is my first try that didn't work:
SELECT RoomNumber, StructureNumber
FROM TimeTables
EXCEPT
SELECT RoomNumber, StructureNumber
FROM TimeTables
WHERE HourNumber = 1 AND DayNumber = 1
At the second time I try to pull the result that dosn't exists in the first query but also didn't work:
SELECT RoomNumber, StructureNumber
FROM TimeTables
WHERE NOT EXISTS(
SELECT RoomNumber, StructureNumber
FROM TimeTables
WHERE HourNumber = 1 AND DayNumber = 1)
I've searched for solutions at the internet and found some things that similar to my problem but none of them worked for me.
NOT EXISTS requires reference from the outer query which you haven't supply
So, your NOT EXISTS should be :
SELECT t.*
FROM TimeTables t
WHERE NOT EXISTS (SELECT 1
FROM TimeTables t1
WHERE t1.RoomNumber = t.RoomNumber and t1.StructureNumber = t.StructureNumber and
t1.HourNumber = 1 AND t1.DayNumber = 1
);
But, for instance where clause should enough
I think this does what you want:
SELECT RoomNumber, StructureNumber
FROM TimeTables
GROUP BY RoomNumber, StructureNumber
HAVING SUM(IIF(HourNumber = 1 AND DayNumber = 1, 1, 0)) = 0;
The HAVING clause counts the number of rows (for each RoomNumber/StructureNumber combination) that match your specified conditions. The = 0 means that there are no such rows.
Simply correlate the NOT EXISTS subquery to main query, facilitated using table aliases, t and sub:
SELECT t.*
FROM TimeTables t
WHERE NOT EXISTS
(SELECT 1
FROM TimeTables sub
WHERE sub.HourNumber = 1 AND sub.DayNumber = 1
AND sub.RoomNumber = t.RoomNumber
AND sub.StructureNumber = t.StructureNumber)
But simply run a WHERE clause reversing the logic:
SELECT t.*
FROM TimeTables t
WHERE t.HourNumber <> 1 OR t.DayNumber <> 1