Query to show all ID's except the ones that have a specific instrument - sql

So I have a table which looks like this:
What would be the best query to exclude every "stuknr" that has atleast 1 "saxofoon" in the "instrumentnaam" column?

To select all stuknr where there is not stuknr with a saxofoon:
SELECT *
FROM table
WHERE stuknr not in (
SELECT stuknr
FROM TABLE
WHERE INSTRUMENTNAAM = ‘saxofoon’)
;

SELECT STUNKR
FROM TABLE
WHERE INSTRUMENTNAAM != ‘saxofoon’;
Here != (or <>, which are equivalent, see this) means "not equal".

You can do this with a NOT IN sub-select
select distinct
YT.stunkr
from
YourTable YT
where YT.stunkr NOT IN ( select distinct stunkr
from YourTable
where InstrumentNaam = 'saxofoon' )
So the sub-select is getting all IDs that DO have saxofoon and the primary select/from is getting where the ID is NOT in the secondary.

Related

Find ID's not match a list

I cannot say I am so experienced with SQL. Here is my question.
A table TripEvent have millions of rows. It contains a column Bold_ID that is indexed and unique.
So I can have this query
select bold_id from TripEvent where bold_id in (354469477, 354469536, 354469500, 987359)
Result is
354469477
354469536
354469500
as those exists. But I want to reverse it. How can I get a list if id's that don't exists ?
In this case it should return one row
987359
I cannot use NOT in query as that would return all rows in table not match my list.
One way is like this:
SELECT DS.*
FROM
(
VALUES (354469477)
,(354469536)
,(354469500)
,(987359)
) DS (bold_id)
LEFT JOIN TripEvent TE
ON DS.[bold_id] = TE.[bold_id]
WHERE TE.[bold_id] IS NULL;
Of course, there are diff ways to populated the DS. I will recommend to populate the search IDs in a temporary table.
Since you are using a SQL Server DB, you can use EXCEPT:
SELECT bold_id FROM
(
SELECT 354469477 AS bold_id
UNION ALL
SELECT 354469536
UNION ALL
SELECT 354469500
UNION ALL
SELECT 987359
) listofValues
EXCEPT
SELECT bold_id
FROM TripEvent;
OR:
SELECT bold_id FROM
(
VALUES (354469477),
(354469536),
(354469500),
(987359)
) listofValues(bold_id)
EXCEPT
SELECT bold_id
FROM TripEvent;
Have a look in the documentation
Found this query on another places. Seems to work. Thanks for the good response :)
SELECT *
from (values (354469477),(354469536),(354469500),(987359)) as v(id)
WHERE NOT EXISTS (SELECT BOLD_ID FROM TripEvent WHERE TripEvent.BOLD_ID = v.id)

SQL Server: Each GROUP BY expression must contain at least one column that is not an outer reference

scenario 1:
I have two tables INFUSION_APP_APPOINTMENT,INFUSION_APP_NURSE_NOTES where
INFUSION_APP_NURSE_NOTES.APPOINTMENT_ID=INFUSION_APP_APPOINTMENT.ID and i want to find out the INFUSION_APP_NURSE_NOTES.ID's where INFUSION_APP_NURSE_NOTES.APPOINTMENT_ID is same.
for eg. if the INFUSION_APP_NURSE_NOTES.APPOINTMENT_ID = 1 and INFUSION_APP_NURSE_NOTES.ID is 12,15,78, then i want to display all the
INFUSION_APP_NURSE_NOTES.ID's where INFUSION_APP_NURSE_NOTES.APPOINTMENT_ID =1.
i use below script
SELECT INFUSION_APP_NURSE_NOTES.APPOINTMENT_ID,INFUSION_APP_NURSE_NOTES.ID
FROM INFUSION_APP_NURSE_NOTES
GROUP BY INFUSION_APP_NURSE_NOTES.APPOINTMENT_ID,INFUSION_APP_NURSE_NOTES.ID
HAVING COUNT(INFUSION_APP_NURSE_NOTES.APPOINTMENT_ID)>1
but it does not gives me any records.
scenario 2:
I am running below script with the intention to get the duplicate records with different INFUSION_APP_NURSE_NOTES.ID's but same INFUSION_APP_NURSE_NOTES.APPOINTMENT_ID.
SELECT INFUSION_APP_NURSE_NOTES.ID,INFUSION_APP_NURSE_NOTES.APPOINTMENT_ID,INFUSION_APP_NURSE_NOTES.TYPE
FROM INFUSION_APP_NURSE_NOTES
WHERE
EXISTS (
SELECT 1 FROM INFUSION_APP_APPOINTMENT
WHERE
INFUSION_APP_NURSE_NOTES.ENABLE=1
AND INFUSION_APP_NURSE_NOTES.APPOINTMENT_ID=INFUSION_APP_APPOINTMENT.ID
GROUP BY INFUSION_APP_NURSE_NOTES.ID
HAVING COUNT(INFUSION_APP_NURSE_NOTES.APPOINTMENT_ID)>1
)
ORDER BY INFUSION_APP_NURSE_NOTES.APPOINTMENT_ID;
but getting below error
SQL Error(164): Each GROUP BY expression must contain at least one
column that is not an outer reference
how to solve it?
i want the only row which has common APPOINTMENT_ID but different n
The question is unclear. Finding duplicates is typically performed using ranking functions like ROW_NUMBER(). This query :
SELECT *,ROW_NUMBER(PARTITION BY APPOINTMENT_ID ORDER BYID) as RN
FROM INFUSION_APP_NURSE_NOTES
WHERE
ENABLE=1
Will rank notes for the same appointment by ID and return 1, 2, 3 etc starting from the earliest note. ORDER BY ID DESC would return 1 for the latest note.
This can be used in a subquery or CTE to find the first, last or or duplicate records, eg :
with notes as (
SELECT *,ROW_NUMBER(PARTITION BY APPOINTMENT_ID ORDER BYID) as RN
FROM INFUSION_APP_NURSE_NOTES
WHERE
ENABLE=1
)
select *
from notes
where RN=1
Will return the first note per appointment while :
where RN>1
Will return only duplicates.
The question doesn't say what should be done with the duplicates though.
If the question is how to return all notes from appointments with multiple notes, a subquery can be used to return the APPOINTMENT_IDs that have more than one note. There's no need to include the INFUSION_APP_APPOINTMENT table though :
SELECT *
FROM INFUSION_APP_NURSE_NOTES
where
ENABLE=1 AND
APPOINTMENT_ID IN ( SELECT APPOINTMENT_ID
FROM INFUSION_APP_NURSE_NOTES
WHERE
ENABLE=1
group by APPOINTMENT_ID
having count(*)>1)
Try this
SELECT INFUSION_APP_NURSE_NOTES.ID,INFUSION_APP_NURSE_NOTES.APPOINTMENT_ID,INFUSION_APP_NURSE_NOTES.TYPE
FROM INFUSION_APP_NURSE_NOTES
WHERE
EXISTS (
SELECT COUNT(B.APPOINTMENT_ID), B.ID
FROM INFUSION_APP_APPOINTMENT A
INNER JOIN INFUSION_APP_NURSE_NOTES B ON B.APPOINTMENT_ID = A.ID
WHERE
B.ENABLE=1
GROUP BY B.ID
HAVING COUNT(B.APPOINTMENT_ID)>1
)
ORDER BY INFUSION_APP_NURSE_NOTES.APPOINTMENT_ID;

Comparing date with the Result Set in Oracle

Below is my query which is going to Generate two rows for me after execution of the query.
SELECT *FROM ELP_COUNTRY,ELP_COUNTRY_Tax where
ELP_COUNTRY.COUNTRY_ID=Elp_Country_Tax.Country_Id
and ELP_COUNTRY.DESCRIPTION='Brasil' and GETENGLISHDESCFROMLISTITEM(ELP_COUNTRY_TAX.TAX_TYPE_ID)='Premiums'
and ELP_COUNTRY_TAX.DEALER_ID is null
This query is returning two rows and again from that rows there is a date named effective date. so again from those rows I want to get the Highest date.
Can anyone help me on this. I am new to Oracle
You could self-join the table with the effective date and evaluate against that by adding something like this: (note the joins may not be correct since I'm just guessing what table the effective date is in and how the tables are related)
and elp_country.effective_date = (select max(e2.effective_date) from elp_country e2 where e2.country_id = elp_country.country_id and elp_country.description = 'Brasil')
Or if it's just a grouping thing you're trying to do then your select would be something like this:
SELECT max(effective_date), column2, column3
FROM ELP_COUNTRY,
ELP_COUNTRY_Tax
where ELP_COUNTRY.COUNTRY_ID=Elp_Country_Tax.Country_Id
and ELP_COUNTRY.DESCRIPTION='Brasil' and
GETENGLISHDESCFROMLISTITEM(ELP_COUNTRY_TAX.TAX_TYPE_ID)='Premiums'
and ELP_COUNTRY_TAX.DEALER_ID is null
group by column2, column3;
You could use the rank function, and wrap that with a "select *" and a where clause predicate filtering the rank of 1, like so:
SELECT * FROM (
SELECT
c.*,
ct.*,
rank() over (order by ct.effective_date) as eff_date_rnk
FROM
ELP_COUNTRY c,
ELP_COUNTRY_Tax ct
WHERE
ELP_COUNTRY.COUNTRY_ID = Elp_Country_Tax.Country_Id
and ELP_COUNTRY.DESCRIPTION='Brasil'
and GETENGLISHDESCFROMLISTITEM(ELP_COUNTRY_TAX.TAX_TYPE_ID)='Premiums'
and ELP_COUNTRY_TAX.DEALER_ID is null
) t
WHERE t.eff_date_rnk = 1;

SQL get rows matching ALL conditions

I would like to retrieve all rows matching a set of conditions on the same column. But I would like the rows only if ALL the conditions are good, and no row if only one condition fails.
For example, taking this table:
|id|name|
---------
|1 |toto|
|2 |tata|
I would like to be able to request if "tata" && "toto" are in this table. But when asking if "tata" and "tuto" are in, I would like an empty response if one of argument is in not in the table, for example asking if "toto" && "tutu" are included in the table.
How can I do that ?
Currently, I'am doing one query per argument, which is not very efficient. I tried several solutions including a subselect or a group+having, but no one is working like I want.
thanks for your support !
cheers
This isn't the most efficient way, but this query would work.
SELECT * FROM table_name
WHERE (name = 'toto' OR name = 'tata')
AND ( SELECT COUNT(*) FROM table_name WHERE name = 'toto') > 0
AND ( SELECT COUNT(*) FROM table_name WHERE name = 'tata') > 0
This is a little vague. If the names are unique, you could count the matching rows that match a where clause:
where name='toto' or name='tata'
If the count is 2, then you know both matched. If name is not unique you could potentially select the first ID (select top 1 id ...) that matches each in a union and count those with an outer select.
Even if you had an arbitrary number of names to match, you could create a stored procedure or code in whatever top-level language you are using to build the select statement.
SELECT 1 AS found FROM hehe
WHERE 1 IN (SELECT 1 FROM hehe WHERE name='tata')
AND 1 IN (SELECT 1 FROM hehe WHERE name='toto')
If name is unique you can simplify to:
SELECT *
FROM tbl
WHERE name IN ('toto', 'tata')
AND (SELECT count(*) FROM tbl WHERE name IN ('toto', 'tata')) > 1;
If it isn't:
SELECT *
FROM tbl
WHERE name IN ('toto', 'tata')
AND EXISTS (SELECT * FROM tbl WHERE name = 'toto')
AND EXISTS (SELECT * FROM tbl WHERE name = 'tata');
Or, in PostgreSQL, MySQL and possibly others:
SELECT *
FROM tbl
WHERE name IN ('toto', 'tata')
AND (SELECT count(DISTINCT name) FROM tbl WHERE name IN ('toto', 'tata')) > 1;

SQL: How to properly check if a record exists

While reading some SQL Tuning-related documentation, I found this:
SELECT COUNT(*) :
Counts the number of rows.
Often is improperly used to verify the existence of a record.
Is SELECT COUNT(*) really that bad?
What's the proper way to verify the existence of a record?
It's better to use either of the following:
-- Method 1.
SELECT 1
FROM table_name
WHERE unique_key = value;
-- Method 2.
SELECT COUNT(1)
FROM table_name
WHERE unique_key = value;
The first alternative should give you no result or one result, the second count should be zero or one.
How old is the documentation you're using? Although you've read good advice, most query optimizers in recent RDBMS's optimize SELECT COUNT(*) anyway, so while there is a difference in theory (and older databases), you shouldn't notice any difference in practice.
I would prefer not use Count function at all:
IF [NOT] EXISTS ( SELECT 1 FROM MyTable WHERE ... )
<do smth>
For example if you want to check if user exists before inserting it into the database the query can look like this:
IF NOT EXISTS ( SELECT 1 FROM Users WHERE FirstName = 'John' AND LastName = 'Smith' )
BEGIN
INSERT INTO Users (FirstName, LastName) VALUES ('John', 'Smith')
END
You can use:
SELECT 1 FROM MyTable WHERE <MyCondition>
If there is no record matching the condition, the resulted recordset is empty.
You can use:
SELECT 1 FROM MyTable WHERE... LIMIT 1
Use select 1 to prevent the checking of unnecessary fields.
Use LIMIT 1 to prevent the checking of unnecessary rows.
SELECT COUNT(1) FROM MyTable WHERE ...
will loop thru all the records. This is the reason it is bad to use for record existence.
I would use
SELECT TOP 1 * FROM MyTable WHERE ...
After finding 1 record, it will terminate the loop.
The other answers are quite good, but it would also be useful to add LIMIT 1 (or the equivalent, to prevent the checking of unnecessary rows.
You can use:
SELECT COUNT(1) FROM MyTable WHERE ...
or
WHERE [NOT] EXISTS
( SELECT 1 FROM MyTable WHERE ... )
This will be more efficient than SELECT * since you're simply selecting the value 1 for each row, rather than all the fields.
There's also a subtle difference between COUNT(*) and COUNT(column name):
COUNT(*) will count all rows, including nulls
COUNT(column name) will only count non null occurrences of column name
Other option:
SELECT CASE
WHEN EXISTS (
SELECT 1
FROM [MyTable] AS [MyRecord])
THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END
I'm using this way:
IF (EXISTS (SELECT TOP 1 FROM Users WHERE FirstName = 'John'), 1, 0) AS DoesJohnExist