Find null or value(s) - tsql

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

Related

How to split one tables rows into multiple child tables?

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

How to find all tables where trigger does not exist

The other day we found a table that had a ModifiedDate column but discovered there was no trigger in place to actually update that column. Now I'm trying to write a script to find all of the tables that have a ModifiedDate column but no trigger to update it.
Here is what I have so far:
SELECT so.name AS 'TableName', sc.name AS 'ColumnName', tr.name AS 'Trigger'
FROM sys.objects so
INNER JOIN sys.columns sc ON sc.object_id = so.object_id
LEFT JOIN sys.triggers tr ON so.object_id=tr.object_id
WHERE so.type = 'U' AND sc.name LIKE '%ModifiedDate%'
AND tr.type = 'TR'
To start, I want to find all of the tables that have both the column and trigger. I'm able to find all of the tables with the ModifiedDate column but when I add in that last where filter AND tr.type = 'TR' it returns nothing. I checked and there are tables in there that have both the column and trigger I'm looking for so I would expect to see those on the list.
SELECT so.name AS 'TableName', sc.name AS 'ColumnName', tr.name AS 'Trigger'
FROM sys.objects so
INNER JOIN sys.columns sc ON sc.object_id = so.object_id
LEFT JOIN sys.triggers tr ON so.object_id=tr.parent_id
WHERE so.type = 'U' AND sc.name LIKE '%ModifiedDate%'
AND tr.type = 'TR'
Your join was wrong on Triggers
Cleaning up your query, to find all tables where there are NO triggers where they perhaps should be:
Select t.name As 'TableName'
,c.name As 'ColumnName'
,tr.name As 'Trigger'
From sys.tables t
Join sys.columns c On c.object_id = t.object_id
Left Join sys.triggers tr On t.object_id = tr.parent_id
Where c.name Like '%ModifiedDate%'
And tr.name Is Null
I took out some superfluous stuff. Selecting against tables removes the need to look for Type = 'U' and the parent_id\object_id relationship is such that you don't need to also enforce it with the Type = 'TR' clause.

sql server 2005/2008 conditional join

Is there such thing like conditional join:
SELECT *
FROM TABLE1 A
IF (a=='TABLE2') THEN INNER JOIN TABLE2 B ON A.item_id=B.id
ELSE IF (a=='TABLE3') THEN INNER JOIN TABLE3 C ON A.item_id=C.id
While a is a field in TABLE1.
I like to use this in stored procedures without using dynamic sql (without writing query as string and EXEC(#query)).
EDIT: I can't write:
IF (a=='TABLE2) THEN queryA
ELSE IF (a=='TABLE3') THEN queryB
Because a is a field of TABLE1.
EDIT: Modified answer based on comment below:
You could try to get clever with some left joins. This will return more columns, so you'd probably want to be more discriminating than just SELECT *.
SELECT *
FROM TABLE1 A
LEFT JOIN TABLE2 B
ON A.item_id = B.id
AND A.a = 'TABLE2'
LEFT JOIN TABLE3 C
ON A.item_id = C.id
AND A.a = 'TABLE3'
WHERE (B.id IS NOT NULL AND A.a = 'TABLE2')
OR (C.id IS NOT NULL AND A.a = 'TABLE3')
Updated the query as requried:
SELECT * FROM
(
SELECT *
FROM TABLE1 A INNER JOIN TABLE2 B
ON A.a='TABLE2' --This will eleminate the table rows if the value of A.a is not 'TABLE2'
AND A.item_id=B.id) A,
(SELECT * FROM
INNER JOIN TABLE3 C
ON A.a='TABLE3' --This will eleminate the table rows if the value of A.a is not 'TABLE3'
AND A.item_id=C.id
) B
) a

How to use "as" to set alias for joined tables in oracle 10

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

Syntax for SQL Not In List?

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.