I have a table with approximately 2 million records in old_parent that I need to split into the table structure below it.
I've tried using something like a CTE using a method I saw here.
Example:
WITH address_ins AS (
INSERT INTO address (address)
VALUES op.address
RETURNING id
)
, parent_ins AS (
INSERT INTO parent (info, parent_address_id)
VALUES (op.info, address_ins.id)
, child_1_ins AS (
INSERT INTO child_1 (thing_1, parent_id)
VALUES (op.thing_1, parent_ins.parent_id)
)
... So On So Forth
SELECT * FROM old_parent op;
But this method does not work because the statements don't recognize op. Am I just missing something small or is there a better way to do this?
I think this is what you're looking for:
WITH ins1 AS (
INSERT INTO parent_address (address,old_parent_id)
SELECT address,id FROM old_parent
RETURNING *
)
, ins2 AS (
INSERT INTO parent (info, parent_address_id)
SELECT op.info,ins1.id
FROM ins1 LEFT OUTER JOIN old_parent op ON op.id = ins1.old_parent_id
RETURNING *
)
, ins3 AS (
INSERT INTO child_1 (thing_1, parent_id)
SELECT op.thing_1,ins2.id
FROM ins2
LEFT OUTER JOIN ins1 ON ins1.id = ins2.parent_address_id
LEFT OUTER JOIN old_parent op ON op.id = ins1.old_parent_id
RETURNING *
)
, ins4 AS (
INSERT INTO child_2 (thing_2, parent_id)
SELECT op.thing_2,ins2.id
FROM ins2
LEFT OUTER JOIN ins1 ON ins1.id = ins2.parent_address_id
LEFT OUTER JOIN old_parent op ON op.id = ins1.old_parent_id
)
, ins5 AS (
INSERT INTO child_attribute (child_1_id,thing)
SELECT ins3.id,op.thing
FROM ins3
LEFT OUTER JOIN ins2 ON ins2.id = ins3.parent_id
LEFT OUTER JOIN ins1 ON ins1.id = ins2.parent_address_id
LEFT OUTER JOIN old_parent op ON op.id = ins1.old_parent_id
)
INSERT INTO other_child_attribute (child_1_id, other_thing)
SELECT ins3.id,op.other_thing
FROM ins3
LEFT OUTER JOIN ins2 ON ins2.id = ins3.parent_id
LEFT OUTER JOIN ins1 ON ins1.id = ins2.parent_address_id
LEFT OUTER JOIN old_parent op ON op.id = ins1.old_parent_id
Related
I have a table in my tsql datatable:
CREATE TABLE dbo.Test
(
Col nVarChar (50) null
)
GO
And then I executed query:
Select
c.name As Name, ty.name as Type, c.max_length As MaxLenght, c.precision As Precision, c.scale As Scale, c.is_nullable As IsNullable, *
From
sys.schemas s
inner join sys.tables t on s.schema_id = t.schema_id
inner join sys.columns c on t.object_id = c.object_id
inner join sys.types ty on ty.system_type_id = c.system_type_id
Where
s.name LIKE 'dbo' AND t.name LIKE 'Test'
The question is... Why there are Two Rows?!
Check this:
SELECT ROW_NUMBER() OVER(PARTITION BY system_type_id ORDER BY system_type_id)
, *
FROM sys.types;
Check the first column for values >1...
There are few types mapping to the same system_type_id. Some names are just an alias for something else...
UPDATE
This question addresses the same issue...
I have read that using cte's you can speed up a select distinct up to 100 times. Link to the website . They have this following example:
USE tempdb;
GO
DROP TABLE dbo.Test;
GO
CREATE TABLE
dbo.Test
(
data INTEGER NOT NULL,
);
GO
CREATE CLUSTERED INDEX c ON dbo.Test (data);
GO
-- Lots of duplicated values
INSERT dbo.Test WITH (TABLOCK)
(data)
SELECT TOP (5000000)
ROW_NUMBER() OVER (ORDER BY (SELECT 0)) / 117329
FROM master.sys.columns C1,
master.sys.columns C2,
master.sys.columns C3;
GO
WITH RecursiveCTE
AS (
SELECT data = MIN(T.data)
FROM dbo.Test T
UNION ALL
SELECT R.data
FROM (
-- A cunning way to use TOP in the recursive part of a CTE :)
SELECT T.data,
rn = ROW_NUMBER() OVER (ORDER BY T.data)
FROM dbo.Test T
JOIN RecursiveCTE R
ON R.data < T.data
) R
WHERE R.rn = 1
)
SELECT *
FROM RecursiveCTE
OPTION (MAXRECURSION 0);
How would one apply this to a query that has multiple joins? For example i am trying to run this query found below, however it takes roughly two and a half minutes. How would I optimize this accordingly?
SELECT DISTINCT x.code
From jpa
INNER JOIN jp ON jpa.ID=jp.ID
INNER JOIN jd ON (jd.ID=jp.ID And jd.JID=3)
INNER JOIN l ON jpa.ID=l.ID AND l.CID=3
INNER JOIN fa ON fa.ID=jpa.ID
INNER JOIN x ON fa.ID=x.ID
1) GROUP BY on every column worked faster for me.
2) If you have duplicates in some of the tables then you can also pre select that and join from that as an inner query.
3) Generally you can nest join if you expect that this join will limit data.
SQL join format - nested inner joins
Join to a table that stores multivalue information
Need to query for null or value(s)
Currently do it with a union
First get the null with an outer join
Second union to get the values
Is there a better approach?
select [docSVsys].[sID]
from [docSVsys] with (nolock)
left outer join [docEnum1] as [jointable] with (nolock)
on [jointable].[enumID] = '142'
and [jointable].[sID] = [docSVsys].[sID]
where [jointable].[sID] is null
Union
Select distinct([Table].[sID])
From [DocEnum1] as [Table] with (nolock)
Where 1 = 1
And [Table].[enumID] = '142'
and [Table].[valueID] in (1,2)
Try this:
select distinct
case
when [jointable].[valueID] in (1,2) then [jointable].[sID]
else [docSVsys].[sID]
end
from [docSVsys] with (nolock)
left outer join [docEnum1] as [jointable] with (nolock)
on [jointable].[enumID] = '142'
and [jointable].[sID] = [docSVsys].[sID]
where [jointable].[sID] is null or [jointable].[valueID] in (1,2)
Tell me if it's OK
I wrote this, and it is wrong syntax, help me fix it, I want 'T' to be an alias of the result of the two inner joins.
select T.id
from table1
inner join table2 on table1.x = table2.y
inner join table3 on table3.z = table1.w as T;
You cannot use aliases to name the "entire" join, you can, however, put aliases on individual tables of the join:
select t1.id
from table1 t1
inner join table2 t2 on t1.x = t2.y
inner join table3 t3 on t3.z = t1.w
In the projection, you will have to use the alias of the table, which defines the id column you are going to select.
You can't directly name the result of a join. One option is to use a subquery:
select T.id
from (
select *
from table1
inner join table2 on table1.x = table2.y
inner join table3 on table3.z = table1.w
) T
Another option is subquery factoring:
with T as (
select *
from table1
inner join table2 on table1.x = table2.y
inner join table3 on table3.z = table1.w
)
select T.id
from T
I am trying to develop a T-SQL query to exclude all rows from another table "B". This other table "B" has 3 columns comprising its PK for a total of 136 rows. So I want to select all columns from table "A" minus those from table "B". How do I do this? I don't think this query is correct because I am still getting a duplicate record error:
CREATE TABLE #B (STUDENTID VARCHAR(50), MEASUREDATE SMALLDATETIME, MEASUREID VARCHAR(50))
INSERT #B
SELECT studentid, measuredate, measureid
from [J5C_Measures_Sys]
GROUP BY studentid, measuredate, measureid
HAVING COUNT(*) > 1
insert into J5C_MasterMeasures (studentid, measuredate, measureid, rit)
select A.studentid, A.measuredate, B.measurename+' ' +B.LabelName, A.score_14
from [J5C_Measures_Sys] A
join [J5C_ListBoxMeasures_Sys] B on A.MeasureID = B.MeasureID
join sysobjects so on so.name = 'J5C_Measures_Sys' AND so.type = 'u'
join syscolumns sc on so.id = sc.id and sc.name = 'score_14'
join [J5C_MeasureNamesV2_Sys] v on v.Score_field_id = sc.name
where a.score_14 is not null AND B.MEASURENAME IS NOT NULL
and (A.studentid NOT IN (SELECT studentid from #B)
and a.measuredate NOT IN (SELECT measuredate from #B)
and a.measureid NOT IN (SELECT measureid from #B))
use NOT EXISTS...NOT IN doesn't filter out NULLS
insert into J5C_MasterMeasures (studentid, measuredate, measureid, rit)
select A.studentid, A.measuredate, B.measurename+' ' +B.LabelName, A.score_14
from [J5C_Measures_Sys] A
join [J5C_ListBoxMeasures_Sys] B on A.MeasureID = B.MeasureID
join sysobjects so on so.name = 'J5C_Measures_Sys' AND so.type = 'u'
join syscolumns sc on so.id = sc.id and sc.name = 'score_14'
join [J5C_MeasureNamesV2_Sys] v on v.Score_field_id = sc.name
where a.score_14 is not null AND B.MEASURENAME IS NOT NULL
AND NOT EXISTS (select 1 from #B where #b.studentid = A.studentid
and a.measuredate = #B.measuredate
and a.measureid = #B.measureid)
and not exists (select 1 from J5C_MasterMeasures z
where z.studentid = A.studentid)
Just so you know, take a look at Select all rows from one table that don't exist in another table
Basically there are at least 5 ways to select all rows from onr table that are not in another table
NOT IN
NOT EXISTS
LEFT and RIGHT JOIN
OUTER APLY (2005+)
EXCEPT (2005+)
Here is a general solution for the difference operation using left join:
select * from FirstTable
left join SecondTable on FirstTable.ID = SecondTable.ID
where SecondTable.ID is null
Of course yours would have a more complicated join on clause, but the basic operation is the same.
I think you can use "NOT IN" with a subquery, but you say you have a multi-field key?
I'd be thinking about using a left outer join and then testing for null on the right...
Martin.