sql Query for multiple column condition based on single column condition - sql

I'm trying to get all the duplicated rows based on a certain conditions in a table.
I'm unable to get it. Here is a look at the table.
Table:
MasterId
TaskId
PostType
1
t1
movies
1
t1
music
2
t2
movies
2
t2
movies
2
t2
movies
3
t3
news
4
t4
movies
MasterId has multiple TaskIds and tasksId's will have multiple 'PostType'.
I 'm trying to get masterId's that have PostType only 'movies' and not 'news' or 'music'.

You can use conditional aggregation logic next to HAVING clause after GROUPing BY MasterId column such as
SELECT MasterId
FROM t
GROUP BY MasterId
HAVING SUM(CASE WHEN PostType = 'movies' THEN 1 ELSE 0 END) = COUNT(*)
Demo

seems like an normal selection clausule that you're looking for.
try this
select
t1.MasterId,
t1.TaskId
from dbo.Table t1
where t1.PostType = 'movies'
and t1.MasterId not in (
select t2.MasterId
from dbo.Table t2
where t2.MasterId = t1.MasterId
and t2.PostType <> 'movies'
)

Related

Setting a column value in the SELECT Statement based on a value existing in another table

I have 2 tables. One table lists all the records of items we track. The other table contains flags of attributes of the records in the first table.
For example, Table 1 has columns
Tab1ID, Name, Address, Phone
Table 2 has these columns
Tab2ID, Tab1ID, FlagName
There is a 1 to Many relationship between Table1 and Table2 linked by Tab1ID.
I'd like to create a query that has all the records from Table1 in it. However, if one of the records in Table2 has a Flagname=Retired (with a matching Tab1ID) then I want a "Y" to show up in the select column list otherwise an "N".
I think it might look something like this:
Select Name, Address, Phone, (select something in table2)
from Table1
where Tab1ID > 1;
It's the subquery in the column that has me stumped.
Pat
You can use exists:
Select t1.*,
(case when exists (select 1
from table2 t2
where t2.tab1id = t1.tab1id and t2.flagname = 'Retired'
)
then 'Y' else 'N'
end) as retired_flag
from Table1 t1;
I would do a normal join returning multiple records, but convert them to bits with case statements. Then use that as the subquery and pull the max value for each bit column.
select
name
,address
,phone
,max(retired_flag)
from (
select
table1.name
,table1.address
,table1.phone
,case when table2.flagname = 'retired' then 1 else 0 end as [retired_flag]
from table1
left join table2
on table1.tab1id = table2.tab1id
where tab1id > 1
) tbl
group by
name
,address
,phone

Join table on Count

I have two tables in Access, one containing IDs (not unique) and some Name and one containing IDs (not unique) and Location. I would like to return a third table that contains only the IDs of the elements that appear more than 1 time in either Names or Location.
Table 1
ID Name
1 Max
1 Bob
2 Jack
Table 2
ID Location
1 A
2 B
Basically in this setup it should return only ID 1 because 1 appears twice in Table 1 :
ID
1
I have tried to do a JOIN on the tables and then apply a COUNT but nothing came out.
Thanks in advance!
Here is one method that I think will work in MS Access:
(select id
from table1
group by id
having count(*) > 1
) union -- note: NOT union all
(select id
from table2
group by id
having count(*) > 1
);
MS Access does not allow union/union all in the from clause. Nor does it support full outer join. Note that the union will remove duplicates.
Simple Group By and Having clause should help you
select ID
From Table1
Group by ID
having count(1)>1
union
select ID
From Table2
Group by ID
having count(1)>1
Based on your description, you do not need to join tables to find duplicate records, if your table is what you gave above, simply use:
With A
as
(
select ID,count(*) as Times From table group by ID
)
select * From A where A.Times>1
Not sure I understand what query you already tried, but this should work:
select table1.ID
from table1 inner join table2 on table1.id = table2.id
group by table1.ID
having count(*) > 1
Or if you have ID's in one table but not the other
select table1.ID
from table1 full outer join table2 on table1.id = table2.id
group by table1.ID
having count(*) > 1

Getting results to display that exist in table 1 but not table 2

I'm new to SQL and am having trouble getting results to display that exist in table 1 but not table 2. I need to display how many times each ID from table 1 has been used in table 2 (including 0 if it has not been used) I can get the ID's that exist in Table 1 to display, but not the ID's that don't exist in Table 2.
I am getting:
ID Count
1
1
1
1
1
1
2
but need:
ID Count
1
1
1
0
1
1
0
1
2
I have tried:
SELECT COUNT (PID) AS [ID Count]
FROM SalesOrderProduct
WHERE PID > = 0
GROUP BY PID;
(just for this column that i can't get the 0 values to display in)
Table 1: PID, Description
Table 2: PID, Status
How can I get the results to display showing all the counts for ID in Table 2, including when the count is 0 using UNION?
Thanks everyone
Try this, you can change the attribute name based on your table structure.
Select t1.id, count(t2.id)
From t1 left join t2
on (t1.id = t2.id)
Group By t1.id;
in this case that your ids are not unique use exists with a count plus a union like:
select distinct tbl.id, 0 cnt --for ids not exists in table2
from table1 tbl
where not exists (select t.id from table2 t where t.id=tbl.id)
union
select t1.id, count(t1.id) cnt ----for ids exists in table2
from table1 t1
where exists (select t2.id from table2 t2 where t1.id=t2.id)
group by t1.id

SQL Join and Count

I want to join two tables and get data against an ID from the first table and count a column record from the second table against the same ID. I want a single query which gives me that output.
Following is a use-case/example for your problem and a proposed solution:
You have two tables User and User_Friends which store user-data and contact-information respectively.
And you want to display the name and number of contacts a user has.
Table User:
id Name
0 A
1 B
2 C
3 D
Table User_Friends:
id friend_id
0 1
0 2
0 3
1 2
1 3
Output:
Name Count(*)
A 3
B 2
C 0
D 0
//Display the Name, number of friends
SELECT Name, count(*)
FROM User, User_Friends
WHERE User.id = User_Friends.id
GROUP BY User_Friends.id
I think you're asking about a query like this:
select t1.id, count(t2.id)
from table1 as t1
left outer join table2 as t2
on t2.table1_id = t1.id
group by t1.id;
select
ID,
(select count(*) from table2 where ID=p.ID) as [count]
from table1 p

Oracle: Check if rows exist in other table

I've got a query joining several tables and returning quite a few columns.
An indexed column of another table references the PK of one of these joined tables. Now I would like to add another column to the query that states if at least one row with that ID exists in the new table.
So if I have one of the old tables
ID
1
2
3
and the new table
REF_ID
1
1
1
3
then I'd like to get
ID REF_EXISTS
1 1
2 0
3 1
I can think of several ways to do that, but what is the most elegant/efficient one?
EDIT
I tested the performance of the queries provided with 50.000 records in the old table, every other record matched by two rows in the new table, so half of the records have REF_EXISTS=1.
I'm adding average results as comments to the answers in case anyone is interested. Thanks everyone!
Another option:
select O.ID
, case when N.ref_id is not null then 1 else 0 end as ref_exists
from old_table o
left outer join (select distinct ref_id from new_table) N
on O.id = N.ref_id
I would:
select distinct ID,
case when exists (select 1 from REF_TABLE where ID_TABLE.ID = REF_TABLE.REF_ID)
then 1 else 0 end
from ID_TABLE
Provided you have indexes on the PK and FK you will get away with a table scan and index lookups.
Regards
K
Use:
SELECT DISTINCT t1.id,
CASE WHEN t2.ref_id IS NULL THEN 0 ELSE 1 END AS REF_EXISTS
FROM TABLE_1 t1
LEFT JOIN TABLE_2 t2 ON t2.ref_id = t1.id
Added DISTINCT to ensure only unique rows are displayed.
A join could return multiple rows for one id, as it does for id=1 in the example data. You can limit it to one row per id with a group by:
SELECT
t1.id
, COUNT(DISTINCT t2.ref_id) as REF_EXISTS
FROM TABLE_1 t1
LEFT JOIN TABLE_2 t2 ON t2.ref_id = t1.id
GROUP BY t1.id
The group by ensures there's only one row per id. And count(distinct t2.ref_id) will be 1 if a row is found and 0 otherwise.
EDIT: You can rewrite it without a group by, but I doubt that will make things easer:
SELECT
t1.id
, CASE WHEN EXISTS (
SELECT * FROM TABLE_2 t2 WHERE t2.ref_id = t1.id)
THEN 1 ELSE 0 END as REF_EXISTS
, ....
FROM TABLE_1 t1