How to select a row with a missing entry in historization? - sql

from the following data basis i need to select all IDQ's which do not have an entry for the 11.11.2011.
IDQ | DATE
----------------
1 | 08.11.2011
1 | 09.11.2011
1 | 10.11.2011
1 | 12.11.2011
1 | 13.11.2011
i can't figure out how to express the sql
select
IDQ
from
TBL_WITH_IDQ T
where not exists ( DATE = '11.11.2011' ) // sql does not the job
Database is a Oracle 11g.
maybe someone can help me?

Try:
select idq
from TBL_WITH_IDQ
group by idq
having max(decode("DATE", '11-Nov-2011',1, 0)) = 0 -- double-quoted keyword column name
(Single pass solution) - if your original table is TBL_WITH_IDQ
On the other hand, if your original table is TBL_WITH_DATES and you want to include IDQs with no entries at all, I'd suggest this variant of Parkyprg's solution:
select IDQ
from TBL_WITH_IDQ t
where not exists
(SELECT null
FROM TBL_WITH_DATES d
where d."DATE" = '11-Nov-2011' and t.idq = d.idq)

select
IDQ
from
TBL_WITH_IDQ T
where IDQ NOT IN ( SELECT IDQ FROM TBL_WITH_DATES where DATE = TO_DATE('11.11.2011','dd.mm.YYYY') )
TBL_WITH_DATES - is the table you used in your question and TBL_WITH_IDQ is the original table where IDQ's are defined.

Do you have a table where IDQ is a unique identifier? Is so, your query can be reformed like this...
SELECT
*
FROM
primary_idq_table
WHERE
NOT EXISTS (SELECT * FROM TBL_WITH_IDQ WHERE DATE = '11.11.2011')

Related

Remove Duplicate Values from Table and leave the ID with the most current date

Not a SQL guru, but I need a SQL statement that will return a table of unique values with the most current date, so remove all the duplicate values based on ID and keep the ID with the most current date.
My current SQL statement is this:
Select Bill_To_Merchant_ID, Agreement_Termination_Notification_Date
From STG.Fact_Agreement
Current result:
Bill_To_Merchant_ID Agreement_Termination_Notification_Date
----------------------------------------------------------------
1 01/09/2020
1 03/09/2020
2 05/09/2020
2 07/09/2020
3 06/09/2020
3 16/09/2020
Expected result:
Bill_To_Merchant_ID Agreement_Termination_Notification_Date
----------------------------------------------------------------
1 03/09/2020
2 07/09/2020
3 16/09/2020
If there are no duplicates, that record remains in the result set.
If you want to actually delete the not most recent records, then use:
DELETE
FROM yourTable t1
WHERE EXISTS (SELECT 1 FROM yourTable t2
WHERE t2.Bill_To_Merchant_ID = t2.Bill_To_Merchant_ID AND
t2.Agreement_Termination_Notification_Date > t1.Agreement_Termination_Notification_Date);
If you instead can tolerate just viewing your data as in the expected output, then aggregation should work:
SELECT
Bill_To_Merchant_ID,
MAX(Agreement_Termination_Notification_Date) AS Agreement_Termination_Notification_Date
FROM yourTable
GROUP BY
Bill_To_Merchant_ID;
I think you just want group by:
select Bill_To_Merchant_ID, max(Agreement_Termination_Notification_Date)
from STG.Fact_Agreement
group by Bill_To_Merchant_ID;

SQL: Selecting record where values in one field are unique based off of most recent date

I'm attempting to write an SQL statement to select records such that each record has a unique PartNo, and I want that record to be based off of the most recent ReceiveDate. I got an answer when I asked this question:
SELECT t.*
FROM Table as t
WHERE t.ReceiveDate = (SELECT MAX(t2.ReceiveDate)
FROM Table as t2
WHERE t2.PartNo = t.PartNo
);
However, this answer assumes that for each ReceiveDate, you would not have the same PartNo twice. In situations where there are multiple records with the same PartNo and ReceiveDate, it does not matter which is selected, but I only want one to be selected (PartNo must be unique)
Example:
PartNo | Vendor | Qty | ReceiveDate
100 | Bob | 2 | 2020/07/30
100 | Bob | 3 | 2020/07/30
Should only return one of these records.
I'm using Microsoft Access which uses Jet SQL which is very similar to T-SQL.
Use NOT EXISTS:
select distinct t.*
from tablename as t
where not exists (
select 1 from tablename
where partno = t.partno
and (
receivedate > t.receivedate
or (receivedate = t.receivedate and qty > t.qty)
or (receivedate = t.receivedate and qty = t.qty and vendor > t.vendor)
)
)
manually set up a standard Aggregate query (sigma icon in ribbon) where grouped on Part No and Date field is set to MAX...
run the query to check to see it returns the values you seek... then while in design view - - select SQL view and this will give you the sql statement...

SQL select entries from table where atribute equals parameter else select * entries

It is possible in SQL (ORACLE) to select all entry from a table where an atribute equals an parameter and if not select all the others entries?
like in this example:
COD | Name
1 | Monday
2 | Thursday
3 | Saturday
parameter=3
when cod equals parameter(cod=3) return entry of cod parameter(cod=3) (including cod and name)
else
return all others entries different from parameter(cod=3) (including cod and name) (like 1 Monday and 2 Thursday)
Is it possible with SQL (oracle), or i need something like PLSQL?
I'd use a correlated query and a non-correlated query:
SELECT COD, NAME
FROM TABLE a
WHERE EXISTS (SELECT 1 FROM TABLE b WHERE b.COD = a.COD AND b.COD = 3)
OR NOT EXISTS (SELECT 1 FROM TABLE c WHERE c.COD = 3)
I'm not sure if I'm following your logic, entirely, however.
And, actually, in cases where it's all from one table it can be simplified to just:
SELECT COD, NAME
FROM TABLE a
WHERE a.COD = 3
OR NOT EXISTS (SELECT 1 FROM TABLE c WHERE c.COD = 3)
IF EXISTS(SELECT 1 FROM TABLE WHERE COD=3)
THEN
SELECT COD, NAME FROM TABLE WHERE COD=3
ELSE
SELECT COD, NAME FROM TABLE
END IF

SQL Remove Duplicates, save lowest of certain column

I've been looking for an answer to this but couldn't find anything the same as this particular situation.
So I have a one table that I want to remove duplicates from.
__________________
| JobNumber-String |
| JobOp - Number |
------------------
So there are multiples of these two values, together they make the key for the row. I want keep all distinct job numbers with the lowest job op. How can I do this? I've tried a bunch of things, mainly trying the min function, but that only seems to work on the entire table not just the JobNumber sets. Thanks!
Original Table Values:
JobNumber Jobop
123 100
123 101
456 200
456 201
780 300
Code Ran:
DELETE FROM table
WHERE CONCAT(JobNumber,JobOp) NOT IN
(
SELECT CONCAT(JobNumber,MIN(JobOp))
FROM table
GROUP BY JobNumber
)
Ending Table Values:
JobNumber Jobop
123 100
456 200
780 300
With SQL Server 2008 or higher you can enhance the MIN function with an OVER clause specifying a PARTITION BY section.
Please have a look at https://msdn.microsoft.com/en-us/library/ms189461.aspx
You can simply select the values you want to keep:
select jobOp, min(number) from table group by jobOp
Then you can delete the records you don't want:
DELETE t FROM table t
left JOIN (select jobOp, min(number) as minnumber from table group by jobOp ) e
ON t.jobob = e.jobob and t.number = e.minnumber
Where e.jobob is null
I like to do this with window functions:
with todelete as (
select t.*, min(jobop) over (partition by numbers) as minjop
from table t
)
delete from todelete
where jobop > minjop;
It sounds like you are not using the correct GROUP BY clause when using the MIN function. This sql should give you the minimum JobOp value for each JobNumber:
SELECT JobNumber, MIN(JobOp) FROM test.so_test GROUP BY JobNumber;
Using this in a subquery, along with CONCAT (this is from MySQL, SQL Server might use different function) because both fields form your key, gives you this sql:
SELECT * FROM so_test WHERE CONCAT(JobNumber,JobOp)
NOT IN (SELECT CONCAT(JobNumber,MIN(JobOp)) FROM test.so_test GROUP BY JobNumber);

oracle - getting 1 or 0 records based on the number of occurrences of a non-unique field

I have a table MYTABLE
N_REC | MYFIELD |
1 | foo |
2 | foo |
3 | bar |
where N_REC is the primary key and MYFIELD is a non-unique field.
I need to query this table on MYFIELD and extract the associated N_REC, but only if there is only one occurrence of MYFIELD; otherwise I need no records returned.
So if I go with MYFIELD='bar' I will get 3, if I go with MYFIELD='foo' I will get no records.
I went with the following query
select * from
(
select
n_rec,
( select count(*) from mytable where mycolumn=my.mycolumn ) as counter
from mytable my where mycolumn=?
)
where counter=1
While it gives me the desired result I feel like I'm running the same query twice.
Are there better ways to achieve what I'm doing?
I think that this should do what you want:
SELECT
my_field,
MAX(n_rec)
FROM
My_Table
GROUP BY
my_field
HAVING
COUNT(*) = 1
You might also try the analytic or windowing version of count(*) and compare plans to the other options:
select n_rec, my_field
from (select n_rec, my_field
, count(*) over (partition by my_field) as Counter
from myTable
where my_field = ?)
where Counter = 1