SQL Query without any joins - where-clause

Following tables:
ReviewPicture(rid, pid)
ArticlePicture(aid, pid)
Picture(pid, filename)
I want to get the ID's of pictures which are neither used in ArticlePicture nor in ReviewPicture without using joins.
That is what i got so far - unfortunately i get every picture in Picture:
select distinct Picture.pid
FROM Picture, ReviewPicture, ArticlePicture
where Picture.pid <> ReviewPicture.pid
AND Picture.pid <> ArticlePicture.pid;

You can use subquery
SELECT DISTINCT Picture.pid FROM Picture
WHERE PID NOT IN (SELECT PID FROM ReviewPicture) AND PID NOT IN (SELECT PID FROM ArticlePicture)

Related

how can I can running status from my table?

I have a below table which has multiple rows with same executionid and different status. How can I get the row which status is running, rows will be exclude if executionid associated with both running and completed status?
Below image is the sample data :
Expected result should be:
Using String_AGG() to get all the status per execution id into one list
Joining that list to the original data and then filtering out the results using NOT LIKE operator, if there are cases that are completed and running then they are not selected
with all_status as (
Select
execution_id,
STRING_AGG (status,', ') as all_status_per_id
from [table]
)
Select
data.*,
all_status.all_status_per_id
from [table] as data
left join all_status
on data.execution_id = all_status.execution_id
where (all_status.all_status_per_id LIKE '%running%' AND all_status.all_status_per_id NOT LIKE '%completed%')
AND status = 'running'
Simple select:
select *
from your_table
where status = 'running';
This is about as basic SQL statement that tou can get. I suggest you get a SQL text, and try a few tutorials.

Want to concatenate column of the second query to the first query but getting errors such as "query block has incorrect number of result columns"

SELECT
ID, PRIM_EMAIL, SEC_EMAIL, PHONE
FROM
STUDENTS.RECORDS
WHERE
ID IN (SELECT ID FROM STUDENTS.INFO WHERE ROLL_NO = '554')
UNION
SELECT NAME
FROM STUDENTS.INFO
WHERE ROLL_NO = '554';
Here Roll_No is a user inserted data so for now I have hard coded it. Basically with the help of ROLL_NO I sort the STUDENTS_INFO table from where I get the ID and based on that I try to get PRIM_EMAIL, SEC_EMAIL, PHONE from the STUDENTS.RECORDS table while matching the foreign keys of both the tables. In addition to the current result set I also want to have the prov_name column.
Any help is very much appreciated. Thank you!
I suspect that you want to put all this information on the same row, which suggests a join rather than union all:
select
r.ID,
r.PRIM_EMAIL,
r.SEC_EMAIL,
r.PHONE,
r.NAME
from STUDENTS.RECORDS r
inner join STUDENTS.INFO i ON i.ID = r.ID
where I.ROLL_NO = '554';
I think the source of your error query block has incorrect number of result columns is coming from trying to union together a table with 4 columns (id, prim_email, sec_email, phone) with 1 column (name).
From your question, I am gathering that you want a single table of id, prim_email, sec_email, phone from students.records and name from students.info.
I think the following query using CTE's might get you (partially) to your final result. You may want to refactor for optimizing performance.
with s_records as ( select * from students.records ),
s_info as ( select * from students.info ),
joined as (
select
s_records.id,
s_records.prim_email,
s_records.sec_email,
s_records.phone,
s_info.name
from s_records
left join s_info
on s_records.roll_no = s_info.roll_no
where roll_np = '554' )
select * from joined
Overall, I think that a join will be part of your solution rather than a union :-)

Microsoft Access Query

I have one settings table that is storing different setting keys for a app built using Microsoft Access
One of the settings key drives how many records should be seen in a dropdown list
The query behind the list is similar to the one below:
Select Top 3 id, name FROM tblRegular
Now, I want to achieve something like this:
Select Top (Select keyValue FROM tblSettings WHERE key="rowNumber") id, name FROM tblRegular
But, using it like this does not work as it fires errors
Could someone tell me if it can be done?
EDIT: The table structure looks similar to the one below:
tblRegular:
id | name
1 'A'
2 'B'
3 'C'
tblSettings:
id | key | keyValue
1 'rowNumber' 2
Thank you!
Consider the pure SQL solution using a correlated subquery to calculate a rowCount that is then used in outer query to filter by number of rows:
SELECT main.id, main.[name]
FROM
(SELECT t.id, t.[name],
(SELECT Count(*) FROM tblRegular sub
WHERE sub.[name] <= t.[name]) AS rowCount
FROM tblRegular t) AS main
WHERE main.rowCount <= (SELECT Max(s.keyValue) FROM tblSettings s
WHERE s.key = 'rowNumber')
Alternatively with the domain aggregate, DMax():
SELECT main.id, main.[name]
FROM
(SELECT t.id, t.[name],
(SELECT Count(*) FROM tblRegular sub
WHERE sub.[name] <= t.[name]) AS rowCount
FROM tblRegular t) AS main
WHERE main.rowCount <= DMax("keyValue", "tblSettings", "key = 'rowNumber'")
This syntax does fail in Access SQL, barking at "Select" with the (localised) message like:
The SELECT sentence contains a reserved word or argument, that is
misspelled or missing, or the punctuation is not correct.
Ok, so, just found out that using the Select statement as it was in the question would have triggered the errors mentioned. So, the approach that worked is to alter the .RowSource of the dropdown on form load and the query placed in the rowsource should look like:
Select Top (" & rowNr & ") id, name FROM tblRegular
where rowNr is fetched using another SQL query or even a DAO/ADO function to retrieve the value from the database

SQL DB2 store query result into variable

Usind a DB2 tables:
This is what is done manually in a table
select app_id from table_app where APP_NAME='App_Temp';
gets me an ID, say it's 234
I copy than and do:
select * form table_roles where role_app_id=234;
gets me a row , which is my desired end result.
Is there a way save the result of the first one into a variable and do the second query without the manual step in between using local variables?
I know, you can query out the information with a very simple join between two tables, but I'd like to know, how it works with variables. Is there a way?
Just can just plug it in:
select *
from table_roles
where role_app_id = (select app_id from table_app where APP_NAME = 'App_Temp');
If there can be more than one match, use in instead of =.
You can also phrase this as a join:
select r.*
from table_roles r join
table_app
on r.role_app_id = a.app_id and APP_NAME = 'App_Temp';
However, this might return duplicates, if two apps have the same name. In that case, use select distinct:
select distinct r.*
from table_roles r join
table_app
on r.role_app_id = a.app_id and APP_NAME = 'App_Temp';

How do I link two values in a nested SQL SELECT query?

I have an SQL Server table JobFiles with columns JobId and FileId. This table maps which file belongs to which job. Each job can "contain" one or more files and each file can be "contained" in one or more job. For every pair such that job M contains file N there's a row (M,N) in the table.
I start with a job id and I need to get a list of all files such that they belong to that job only. I have hard time writing a request for that. So far I've crafted the following (pseudocode):
SELECT FileId FROM JobFiles WHERE JobId=JobIdICareAbout AND NOT EXISTS
(SELECT * FROM JobFiles WHERE FileId=ThatSameFileId AND JobId<>JobIdICareAbout);
The above I believe would work but I have a problem of how to map ThatSameFileId onto the FileId returned from the outer SELECT so that the database knows that those are the same.
How do I do that? How do I tell the database that FileId in the outer SELECT must be equal to the FileId in the inner SELECT?
How about using NOT IN:
SELECT FileId FROM JobFiles WHERE JobId=JobIdICareAbout AND FileID NOT IN
(SELECT FileId FROM JobFiles WHERE JobId<>JobIdICareAbout);
And a slight variation on that:
SELECT FileId FROM JobFiles WHERE JobId=JobIdICareAbout
EXCEPT
SELECT FileId FROM JobFiles WHERE JobId<>JobIdICareAbout
I'm taking another approach here but if I understood your problem correctly, it would generate the result you need.
Gist of it goes like this
Get all FileId's from the JobId you care about
JOIN back with the JobFiles tabel
Retain only those FileId's that have no other JobId using a HAVING clause.
SQL Statement
SELECT jf1.FileId
FROM JobFiles jf1
INNER JOIN (
SELECT FileId
FROM JobFiles
WHERE JobID = JobIdICareAbout
) jf2 ON jf2.FileID = jf1.FileID
GROUP BY
jf1.FileId
HAVING COUNT(*) = 1
Another approach:
LEFT JOIN will only find rows if this file is linked to another job, checking for IS NULL removes those files:
SELECT JobFiles.FileId
FROM JobFiles
LEFT JOIN JobFiles OtherJobFiles ON ( OtherJobFiles.FileId = JobFiles.FileId
AND OtherJobFiles.JobId <> JobIdICareAbout )
WHERE JobFiles.JobId=JobIdICareAbout
AND OtherJobFiles.FileId IS NULL
It seems you have a lot of (different but) working answers/queries. Here's one more using NOT EXISTS. It's only a correction of what you tried:
SELECT jf.FileId
FROM JobFiles jf
WHERE jf.JobId = JobIdICareAbout
AND NOT EXISTS
( SELECT 1
FROM JobFiles jf2
WHERE jf2.FileId = jf.FileId
AND jf2.JobId <> JobIdICareAbout
)