I have 2 tables: 1 master table and 1 that I'm trying to put together.
TABLE1: ID (AUTOINCREMENT) NAME PARENT
TABLE2: ID(AUTOINCREMENT) PARENT CHILD
SQL code:
INSERT INTO TABLE2 (PARENT, CHILD)
SELECT TABLE1.PARENT, TABLE1.ID
FROM TABLE1
WHERE TABLE1.PARENT = (SELECT DISTINCT TABLE1.PARENT FROM TABLE1)
So I want my query to go over all the PARENTs and one by one get all its children.
Obviously it's not working and it is returning only the first PARENT and its children IDs
Yes you can, using IN instead of =.
Try this:
INSERT INTO TABLE2 (PARENT, CHILD)
SELECT TABLE1.PARENT, TABLE1.ID
FROM TABLE1
WHERE TABLE1.PARENT IN (SELECT DISTINCT TABLE1.PARENT FROM TABLE1)
That query would produce the exact same results as the much simpler:
INSERT INTO TABLE2 (PARENT, CHILD)
SELECT PARENT, ID
FROM TABLE1
The subquery in the where clause has no effect. It's basically saying, please insert parent and id from table 1 where parent and id are in table 1. They will all be.
Now if you were using a separate table in the subquery this might make sense. But even then I would suggest simply joining like so:
INSERT INTO TABLE2 (PARENT, CHILD)
SELECT TABLE1.PARENT, TABLE1.ID
FROM TABLE1
JOIN
(SELECT DISTINCT PARENT FROM TABLE2) TABLE2
ON TABLE1.PARENT = TABLE2.PARENT
Related
I want to get a value from an IN subquery with two columns, without needing to do two queries.
Sample:
SELECT * FROM table1 WHERE id IN(SELECT id, flags FROM table2);
Now I want to get flags directly. Is it possible, and if yes, how?
Any help is appreciated :)
It sounds like you are trying to achieve one of two things:
1) Select every field of records in table1 (and the associated table 2 flag) where the record's id is also found in the id column of table2. If that is the case, then yes, a join will accomplish what you want:
SELECT t1.*,
t2.flags
FROM table1 t1
JOIN table2 t2
ON t1.id = t2.id;
Note that JOIN is used here (rather than other types of joins such as LEFT JOIN) because JOIN will return only table1 records with a match in table2.id. LEFT JOIN, on the other hand, would return every table1 record, and table1 ids without a match in table2 would simply have null in the flags column of your returned table.
2) Select every field of records in table1 where the record's id is also found in either the id column of table2 or the flags column of table2. If that is the case, there are a few ways you could get the desired result, but achieving this using a subquery similar to the question
SELECT *
FROM table1
WHERE id IN (SELECT id FROM table2 UNION DISTINCT SELECT flags FROM table2)
You do this using join:
SELECT t1.*, t2.flags
FROM table1 t1 JOIN
table2 t2
ON t1.id = t2.id;
I want to delete an entry in a table where multiple fields match the results of another select subquery which takes data from another table.
query :
DELETE FROM table1
WHERE carriedby_circuit IN (SELECT
circuit_id
FROM table2
WHERE circuit_name IN (SELECT
t.sc_prod_service_id
FROM table3 t));
So I want to modify the query in such a way that if circuit_id form table2 is present in carriedBY_circuit or in CARRIED_CIRCUIT columns of table1. it should delete the row from table1.
You can try with merge:
merge into table1 t1
using (select t2.circuit_id from table2 t2 inner join table3 t3 on t2.circuit_name = t3.sc_prod_service_id) d
on (d.circuit_id = t1.carriedby_circuit or d.circuit_id = t1.carried_circuit)
when matched then delete;
Assuming you have 3 tables and you are working with ids. Table1, table2 and table3. Your best approach is to join table2 with table3. Then query its results, to delete from table1.
Example:
DELETE FROM table1
WHERE table1.id IN(SELECT distinct id FROM tabel1 UNION SELECT ID as id FROM tabel2);
PS: The union select will probably duplicate your Id´s, this is why I propose to use distinct.
I have table1 with columns:
def_id, def_name, username etc
I have another table table2 which has some association:
assoc_id,parent_id,child_id
The parent_id , child_id are actually def_id's from Table1 . They get inserted into Table2 based on parent_child relation user action in GUI.
Now I want to select all def_id for a particular username from Table1 and then use that input to delete all the records if those def_ids are part of the parent_id or child_id from Table2.
How do I do this in SQL? I am using Sybase database.
Any help will be appreciated
Delete Table2
Where parent_id In
(Select def_id from table1
Where username = #username) Or
child_id In
(Select def_id from table1
Where username = #username)
Or
Delete t2
From table2 t2
Where Exists
(Select * From Table1
Where def_id In
(t2.parent_Id, t2.child_Id))
An easy way is adding a subquery to the where clause.
DELETE ab
FROM AuthorArticle AS ab
WHERE ab.AuthID=(SELECT AuthID FROM Authors WHERE AuthorLastName='Yin')
Never used Sybase, but this is basic SQL and should work.
Try:
DELETE table2
FROM table2
INNER JOIN table1 ON table1.def_id IN (table2.parent_id, table2.child_id)
03-30 13:17]
I'm trying to use a t-sql against SQL-Server 2005 with asp 3.0. What I want to do is first select all rows that match a certain condition and then I want to know how how many children are connected to that row based on it's ChildID.
This can of course be done by just doing two queries against the db one to get the matching rows for the Parent and one for each row that was found to know how many children have that as Parent.
I have two tables, table1 contains parents and children and table2 contains the information and the id here is ofcourse the id that is saved in parent and children in table1.
Now I want to first find all the children to a certain parent, and in the same sql-statement I want to know how many children is connected to each child.
So Parent 807 has two children, 808 and 809. 808 has 5 children and 809 has 72 children, how can I with one statement get both the information of children 808 and 809 and the numer of children connected to each of them.
My SQL looks like this (gets the children to parent 807)
SELECT Parent, Child, ID, FieldX, FieldY
FROM Tabel1 INNER JOIN Tabel2 ON Parent = ID
WHERE (Parent = 807)
The statement I use to get the numer of children connected to f.ex. 808 is as follows.
SELECT COUNT(*) AS AntalPoster
FROM Tabel1 INNER JOIN Tabel2 ON Child = ID
WHERE (Parent = 808)
What I would like to do is the following, but I would like to substitute the value 808 with the value each record gives me for the child aka SearchID.
SELECT Parent, Child AS SearchID, ID, FieldX, FieldY,
(SELECT COUNT(*) AS [Antal sidor]
FROM Tabel1 INNER JOIN Tabel2 ON Child = ID
WHERE (Parent = 808)) AS AntalPoster
FROM Tabel1 INNER JOIN Tabel2 ON Child = ID
WHERE (Parent = 807)
The problem I get is that "Invalid column name 'SearchID'", what I can understand is that I can't get the value that I find in SerachID to be used as a value in the next SQL-statements where clause.
Is this possible, and if so how?
Thanks in advance.
So, I understand, basically Table1 contains hierarchy information, and Table2 details.
Assuming that, here's my approach:
SELECT
h.Parent,
h.ChCount,
d.* /* you may want to expand it to a specific Table2 column list */
FROM (
/* first, get the children and their child counts */
SELECT
p.Parent,
p.Child,
COUNT(*) AS ChCount
FROM Table1 p
INNER JOIN Table1 c ON p.Child = c.Parent
GROUP BY p.Parent, p.Child
WHERE p.Parent = 807
) h
/* next, get the children's details */
INNER JOIN Table2 d ON h.Child = d.ID
Now I want to first find all the children to a certain parent, and in the same sql-statement I want to know how many children is connected to each child.
This is a way to do that.
declare #Table1 table (Table1ID int, ParentID int)
-- Root
insert into #Table1 values(807, null)
-- Children to 807
insert into #Table1 values(808, 807)
insert into #Table1 values(809, 807)
-- Children to 808
insert into #Table1 values(810, 808)
-- Children to 809
insert into #Table1 values(811, 809)
insert into #Table1 values(812, 809)
select
T1.*,
(select count(*)
from #Table1 as T2
where T1.Table1ID = T2.ParentID) as ChildCount
from #Table1 as T1
where T1.ParentID = 807
Result
Table1ID ParentID ChildCount
----------- ----------- -----------
808 807 1
809 807 2
Replace
WHERE (Parent = SearchID))
by
WHERE (Parent = ParentID))
But you're better of using
SELECT Parent, Child, ID, FieldX, FieldY, COUNT(*) AS AntalPoster
FROM Tabel1 INNER JOIN Tabel2 ON Child = ID
WHERE (Parent = [ParentID])
GROUP
BY Parent, Child, ID, FieldX, FieldY;
If you define a "alias" for a column you can't use this name inside the query earlier than within a group by or order by clause.
As is your example SearchID is just a name for column Child you should use WHERE (PARENT = Child)
You're kinda close.
SELECT Parent_ID, COUNT(*) AS AntalPoster FROM Tabel1 INNER JOIN Tabel2 ON Child = ID
Group by Parent_ID
Now I don' quite understand from reading your question what the 'ID' field is called...but the results of this query should give the Parent_ID along with the count of the number of child records (If I've read your setup corectly). Join to that subquerty to get the count.
SELECT Parent, Child.AntalPoster, ID, FieldX, FieldY
FROM Tabel1 INNER JOIN Tabel2 ON Parent = ID
inner join (SELECT Parent_ID, COUNT(*) AS AntalPoster FROM Tabel1 INNER JOIN Tabel2 ON Child = ID Group by Parent_ID) child on child.id = t1.ID
WHERE (Parent = 807)
Whats really confusing me in your example...if I'm still off with what you're going for...quickly giving us the schema would help. Is the table setup so it has Parent, Child, ID? If so, how does the work? I'd expect Parent_ID, Child_ID...bit confused on the third "ID" column, what does it hold thats unique from the parent,child columns that already exist?.
In any case, the logic is setup a subquery so it reads Key , Count(1). Then join to that subquery on the Key to obtain the count value the subquery returns.
Duplicate:
How to do a Select in a Select
I have 2 tables:
TABLE1
Table1Id
TABLE2
Table2Id
Table1Id
UserId
TABLE2 has thousands of entries in it. I want to return a list of TABLE1 entries where there isn't an entry in TABLE2 for it for a particular user. So, where there isn't a foreign key entry in TABLE2. A query like:
select count(*) from TABLE1 where Table1Id not in (
select Table1Id from TABLE2 where id_user = 1)
However, that query runs very slowly. What would be the most efficient way of getting the results I require?
There is a similar question
I think it would be better
SELECT COUNT(*)
FROM TABLE1
WHERE NOT EXISTS (SELECT Table1Id FROM TABLE2 WHERE TABLE2.Table1Id = TABLE1.Table1Id AND UserID = 1)
I would check the indexes also, as ck suggested
What about
select Table1Id from TABLE1
minus
select Table1Id from TABLE2 where id_user = 1
I am not sure, it MsSql support minus. If not, you should try a correlated subquery.
You can also use the 'EXCEPT/MINUS' intersect to get only differences between the two tables as long as the selection returns the same field types/order.
SELECT TABLE1ID
FROM TABLE1
EXCEPT -- or MINUS in Oracle
SELECT TABLE1ID
FROM TABLE2
WHERE USER_ID = 1
See How to do a Select in a Select
Also, make sure that any fields you are querying have a suitable index.