sql - confusion with correlated subqueries - sql

I have been using suggestions given to me in an earlier question regarding subqueries. See here:
sql - multiple layers of correlated subqueries
SQL Server : left join results in fewer rows than in left table
I am using ms sql server (I believe it is 2005).
What I am trying to do now is the following:
I have a result of rows (call it result A), that is obtained from doing the following:
select * from TableA as a
join (select * from TableB where RealDate = '4/20/2013 12:00:00 AM') as b
on a.id = b.id
Of this result I want to find all rows that are NOT in the result of rows returned by this query:
select * from TableA as a
join TableC as c
on c.id = a.id
Essentially I have a situation where the first query results in 246 records, while the second query results in 247 records. I was expecting the first result to return 247 records (all of which should be in the list of records returned by the second query). So now I need to investigate which record is missing so I can take proper action.
I tried to do something like the following but received various errors:
select * from (select * from TableA as a
join (select * from TableB where RealDate = '4/20/2013 12:00:00 AM') as b
on a.ul_id = b.id))
as result_A
where not exists (select 1 from (select * from TableA as a
join TableC as c
on c.id = a.ul_id) as result_B
where result_A.ul_id = result_B.id);

Do this set difference:
select a.* from TableA as a
join TableC as c
on c.id = a.id
except
select a.* from TableA as a
join (select * from TableB where RealDate = '4/20/2013 12:00:00 AM') as b
on a.id = b.id
If for some reason this does not return a row, then the first query has a duplicate.

Your narrative says you want to exclude results from:
select * from TableA as a
join TableC as c
on c.id = a.id
but your not exists has a different subquery. Also, some of your errors may have been caused by using the same alias more than once.
Finally, Pieter's approach should work. I didn't check the details.

Related

SQL Get rows that doesn't appear in another table

I have this SQL problem: I have tables A and B. Table A has columns id and name, Table B amount and id which is a foreign key to table A.id.
I need to return all table A rows that don't have their id stored in table B. Any ideas?
So the complete opposite is:
SELECT *
FROM a
LEFT OUTER JOIN b ON a.id = b.id;
Here row what I need is left out of result
Just add a where clause:
SELECT a.*
FROM a LEFT OUTER JOIN
b
ON a.id = b.id
WHERE b.id IS NULL;
You can also use NOT EXISTS:
select a.*
from a
where not exists (select 1 from b where b.id = a.id);
In most databases, the two methods typically have similar performance.

Main query results in Subquery

How can we use reference of main query result set as a source table in subquery
Table A, Table C
Select
(Select * From a)
From
(Select tabA.*
From A tabA
Join C tabC
On tabA.id = tabC.id) as a
I got invalid object a error here
Presumably, you want a common table expression (CTE):
with a as (
select tabA.*
from A tabA Join
C tabC
on tabA.id = tabC.id
)
Select (Select * from a)
From a;
That said, your query makes no sense. The scalar subquery is probably going to be returning an error, either because of the number of rows or number of columns.
if you using sqlserver than modified your query based on below query.
select * from
(select A.* from TableA A inner join TableB B on A.EmployeeID = B.EmployeeID ) a

How to overcome the error on join union tables with other table

While we try to join between union tables on one side with other table on the other side,
SELECT A.x,B.y FROM ([DataSet.Liad],[DataSet.Livne]) AS A INNER JOIN [DataSet.Names] AS B ON A.ID = B.ID LIMIT 10
we get this error:
Error: 2.1 - 0.0: JOIN cannot be applied directly to a table union or to a table wildcard function. Consider wrapping the table union or table wildcard function in a subquery (e.g., SELECT *).
In order to solve this error I suggest you to use a View.
Save this Query of union as a View, DataSet.LiadLivne:
SELECT * FROM [DataSet.Liad],[DataSet.Livne]
Execute the origin query using the view:
SELECT A.x,B.y FROM [DataSet.LiadLivne] AS A INNER JOIN [DataSet.Names] AS B ON A.ID = B.ID LIMIT 10
Enjoy
You need to write as:
SELECT A.x,
B.y
FROM
(SELECT A.x
FROM ([DataSet.Liad],[DataSet.Livne])) AS A
INNER JOIN [DataSet.Names] AS B ON A.ID = B.ID LIMIT 10

Select returns the same row multiple times

I have the following problem:
In DB, I have two tables. The value from one column in the first table can appear in two different columns in the second one.
So, the configuration is as follows:
TABLE_A: Column Print_group
TABLE _B: Columns Print_digital and Print_offset
The value from the different rows and Print_group column of the Table_A can appear in one row of the Table_B but in different column.
I have the following query:
SELECT DISTINCT * FROM Table_A
INNER JOIN B ON (Table_A. Print_digital = Table_B.Print_group OR
Table_A.Print_offset = Table_B.Print_group)
The problem is that this query returns the same row from the Table_A two times.
What I am doing wrong? What is the right query?
Thank you for your help
If I'm understanding your question correctly, you just need to clarify your fields to come from Table_A:
SELECT DISTINCT A.*
FROM Table_A A
INNER JOIN B ON A.Print_digital = B.Print_group
OR A.Print_offset = B.Print_group
EDIT:
Given your comments, looks like you just need SELECT DISTINCT B.*
SELECT DISTINCT B.*
FROM Table_A A
INNER JOIN B ON A.Print_digital = B.Print_group
OR A.Print_offset = B.Print_group
I've still another question... first,to be clear, the right query version is
SELECT DISTINCT A.*
FROM Table_A A
INNER JOIN B ON A.Print_digital = B.Print_group
OR A.Print_offset = B.Print_group.
If I want it returns also one column from the B table it again returns duplicate rows. My query (the bad one) is the following one:
SELECT DISTINCT A.*, B.Id
FROM Table_A A
INNER JOIN B ON A.Print_digital = B.Print_group
OR A.Print_offset = B.Print_group

How to select records from a Table that has a certain number of rows in a related table in SQL Server?

Not quite sure how to ask this, but I have 2 tables that are related in a 1 to many relationship, I need to select all records in the "1" table that have less than three records in the "many' table.
select b.foreignkey,count(b.foreignkey) as bidcount
from b
where b.foreignkey in (select a.id from a) and bidcount< 3
group by b.foreignkey
this doesn't work at all I know but I am at a loss how to do this.
I need to in the end select all the records from the "a" table based on this criteria. Sorry if that is confusing!
Just using your code, not tested:
SELECT
b.foreignkey,
count(b.foreignkey) as bidcount
FROM
b
WHERE
b.foreignkey IN (SELECT a.id FROM a)
GROUP BY
b.foreignkey
HAVING
count(b.foreignkey) < 3
Try this:
SELECT t1.id,COUNT(t2.parentId)
FROM table1 as t1
INNER JOIN table2 as t2
ON t1.id = t2.parentId
GROUP BY t1.id
HAVING COUNT(t2.parentId) < 3
You didn't mention which version of SQL Server you're using - if you're on SQL Server 2005 or newer, you could use this CTE (Common Table Expression):
;WITH ChildRows AS
(
SELECT A.Id, COUNT(b.Id) AS 'BCount'
FROM
dbo.TableA A
INNER JOIN
dbo.TableB B ON B.TableAId = A.Id
)
SELECT A.*, R.BCount
FROM dbo.TableA A
INNER JOIN ChildRows R ON A.Id = R.Id
The inner SELECT lists the Id columns from TableA and the count of the child rows associated with those (using the INNER JOIN to TableB) - and the outer SELECT just builds on top of that result set and shows all fields from table A (and the count from the B table)
if you want to return all fields of your (1) table in one query, I suggest you consider using CROSS APPLY:
SELECT t1.* FROM table_1 t1
CROSS APPLY (SELECT COUNT(*) cnt FROM Table_Many t2 WHERE t2.fk = t1.pk) a
where a.cnt < 3
in some particular cases, based on your indices and db structure, this query may run 4 times faster than the GROUP BY method
you have posted this question in sql server, I have a answer in oracle database system (don't know whether it will run in sql server as well or not)
this is as follow-
select [desired column list] from
(select b.*, count(*) over (partition by b.foreignkey) c_1
from b
where b.foreignkey in (select a.id from a) )
where c_1 < 3 ;
i hope it should work on sql server as well...
if not please let me update ..