Converting nested Selects in WHERE .. OR .. to INNER JOINS - sql

How would I convert the following to use INNER JOIN rather than nested SELECT?
SELECT
[Name].[NameValueID],
[Name].[NameTypeID],
[Name].[NameID],
[Name].[Value]
FROM [Name]
WHERE Name.NameTypeID IN ( SELECT NameTypeID FROM #tbNameType )
OR Name.NameID IN ( SELECT NameID FROM #tbName)

This one's tricky because it's an "OR" condition rather than an "AND". But I think this would do it:
SELECT
[Name].[NameValueID],
[Name].[NameTypeID],
[Name].[NameID],
[Name].[Value]
FROM [Name]
INNER JOIN ( SELECT NameTypeID FROM #tbNameType ) t ON t.NameTypeID=Name.NameTypeID
UNION
SELECT
[Name].[NameValueID],
[Name].[NameTypeID],
[Name].[NameID],
[Name].[Value]
FROM [Name]
INNER JOIN ( SELECT NameID FROM #tbName) t ON t.NameID = Name.NameID

SELECT DISTINCT
Name.NameValueID,
Name.NameTypeID,
Name.NameID,
Name.Value
FROM
Name
LEFT JOIN #tbNameType a ON a.NameTypeID=Name.NameTypeID
LEFT JOIN #tbName b ON b.NameID=Name.NameID
WHERE a.NameTypeID IS NOT NULL OR b.NameID IS NOT NULL

Related

How to use a created column as a JOIN parameter SQL query

I have 3 Tables of Data which i am trying to Join (TEXTDATA, STOREDATA, SALESDATA). My TEXTDATA has a name string within on of the columns so have created a substring to find it.
I am trying to then used that newly formed string (name) as the basis to join to the SALESDATA table.
Here is my code
SELECT b.*,
a.text,
a.textname,
SUBSTRING(a.[textname], CHARINDEX('/ ', a.[textname]) + 1, 11) AS NAME,
c.[Sales],
c.[Customer],
c.[Class]
FROM [dbo].[TEXTDATA] a
INNER JOIN [dbo].[STOREDATA] b
ON a.[ID_TEXTDATA] = b.[ID_STOREDATA]
LEFT JOIN [dbo].[SALESDATA] c
ON NAME = c.FirstName
With the error saying Invalid column name 'name'
Any ideas on how to reference the new column made later in a query?
Thanks very much!
Easiest option is just to use the same formula in the LEFT JOIN's ON clause:
LEFT JOIN [dbo].[SALESDATA] c
ON SUBSTRING(a.[textname],CHARINDEX('/ ',a.[textname])+1,11) = c.FirstName
Or you could put the formula in a CTE abstraction of your TEXTDATA table:
;with cte AS (
SELECT [ID_TEXTDATA], text, textname, SUBSTRING(a.[textname],CHARINDEX('/ ',a.[textname])+1,11) as name
From [dbo].[TEXTDATA] a
)
SELECT b.*
,cte.text
,cte.textname
,cte.name
,c.[Sales]
,c.[Customer]
,c.[Class]
From
cte
INNER JOIN [dbo].[STOREDATA] b
on cte.[ID_TEXTDATA] = b.[ID_STOREDATA]
LEFT JOIN [dbo].[SALESDATA] c
on cte.name = c.FirstName
Select b.*
,a.text
,a.textname
,SUBSTRING(a.[textname],CHARINDEX('/ ',a.[textname])+1,11) as name
,c.[Sales]
,c.[Customer]
,c.[Class]
From
[dbo].[TEXTDATA] a
INNER JOIN [dbo].[STOREDATA] b
on a.[ID_TEXTDATA] = b.[ID_STOREDATA]
LEFT JOIN [dbo].[SALESDATA] c
on SUBSTRING(a.[textname],CHARINDEX('/ ',a.[textname])+1,11) = c.FirstName
First, join takes place and can't find the name
I think you should try this in your ON CLAUSE:
SUBSTRING(a.[textname],CHARINDEX('/ ',a.[textname])+1,11)
Select b.*,a.text,a.textname,SUBSTRING(a.[textname],CHARINDEX('/ ',a.[textname])+1,11)
as name,c.[Sales] ,c.[Customer],c.[Class]
From [dbo].[TEXTDATA] a
INNER JOIN [dbo].[STOREDATA] b
on a.[ID_TEXTDATA] = b.[ID_STOREDATA]
LEFT JOIN [dbo].[SALESDATA] c
on SUBSTRING(a.[textname],CHARINDEX('/ ',a.[textname])+1,11) = c.FirstName
You can't reference the column alias name on the same level.
You have to use the entire expression on the ON
ON SUBSTRING(a.[textname],CHARINDEX('/ ',a.[textname])+1,11) = c.FirstName
Or you can make use of a CTE or derived query and compose the expression name in the CTE or derived query.
with Text_Data as
(
SELECT *,
SUBSTRING(a.[textname],CHARINDEX('/ ',a.[textname])+1,11) as [name]
FROM [dbo].[TEXTDATA] a
)
Select b.*
,a.text
,a.textname
,a.name
,c.[Sales]
,c.[Customer]
,c.[Class]
From
Text_Data a
INNER JOIN [dbo].[STOREDATA] b
on a.[ID_TEXTDATA] = b.[ID_STOREDATA]
LEFT JOIN [dbo].[SALESDATA] c
on a.name = c.FirstName
Or alternatively use a CROSS APPLY to compute the expression and then use it in the JOIN
Select b.*
,a.text
,a.textname
,n.name
,c.[Sales]
,c.[Customer]
,c.[Class]
From
[dbo].[TEXTDATA] a
CROSS APPLY
(
SELECT SUBSTRING(a.[textname],CHARINDEX('/ ',a.[textname])+1,11) as name
) n
INNER JOIN [dbo].[STOREDATA] b
on a.[ID_TEXTDATA] = b.[ID_STOREDATA]
LEFT JOIN [dbo].[SALESDATA] c
on n.name = c.FirstName
As the order of execution of SQL query says the select statement is run after all join statements so you can use alias in select for manipulation but not the same manipulated alias in join as join has already run by that time instead ypu need to have an extra select on top of it or using a WITH CLAUSE Subquery
Select *, name from ( select *,.. as
name from table) left join othertable
t1 on
name=t1.value
Or using WITH CLAUSE
WITH data as
( select *,.. as name from table)
Select * from data left join table1 t1
on data.name=t1.value

How to fix "ABAP INNER JOIN"

i'm trying to get a inner join from two select sentences but it doesn't work, what i am doing wrong?
i cant work with internal tables because inner join doesn't permit it.
clear: it_spfli.
refresh: it_spfli.
select
spfli-cityto
spfli-cityfrom
into TABLE it_spfli from(select spfli-cityto COUNT( * )from spfli group by spfli-cityto) as t1
INNER JOIN(select spfli-cityfrom COUNT( * )from spfli group by spfli-cityfrom) as t2
ON t1-cityto = t2-cityfrom.
i expect a table of more frequency city to and city from order by city to with table spfli.
First of all i don't think you are doing the right SELECT to get what you want.
I answer this question from the technical perspective. You can use WITH.
WITH +spf1 AS (
SELECT spfli~cityto AS cityto, COUNT(*) AS count FROM spfli GROUP BY spfli~cityto ) ,
+spf2 AS (
SELECT spfli~cityfrom AS cityfrom , COUNT(*) AS count FROM spfli GROUP BY spfli~cityfrom ) ,
+spf3 AS (
SELECT s1~cityto, s2~cityfrom FROM +spf1 AS s1 INNER JOIN +spf2 AS s2
ON s1~cityto = s2~cityfrom )
SELECT * FROM +spf3 INTO TABLE #DATA(lt_result).

I have two tables i want to join them in my SQL to retrieve results

i have two table ork3,ork2 i want to sum column k1 join table ork3>>>>>>>>>>
This should do what you want:
SELECT [name]
, [date]
, [dep]
, [sum(k1)]
FROM ork3
INNER JOIN
(SELECT [name]
, SUM([k1]) AS [sum(k1)]
FROM ork2
GROUP BY [name]) AS ork2 ON ork3.[name] = ork2.[name];
You could do;
Select name, sum(k1) From ork3 o3 Inner Join ork2 o2 On o2.name = o3.name group by o3.name;

MSSQL Inner Join on Concatenated Column

I'm not a DBA so please don't yell at me. Trying to do an inner join and Group By using a concatenated column. The ON statement is producing a syntax error. I do not have access to the original tables and am trying to normalize this into another table, I know its ugly. Not overly worried about performance, just need to work. Cant use functions either.
SELECT DISTINCT A.[carrier_code],[carrier_name], [carrier_grouping], A.[collector_name], [dataset_loaded], [docnum], [envoy_payer_id], [loc], [market], [master_payor_grouping], [plan_class], [plan_name], A.[resp_ins],A.[resp_ind], A.[resp_payor_grouping], A.[Resp_Plan_Type], A.[rspphone], A.[state], A.[sys],A.[resp_ins]+A.[resp_payor_grouping]+A.[carrier_code]+A.[state]+A.[Collector_Name] as ExtId
FROM [Table1] A
INNER JOIN
(SELECT [resp_ins]+[resp_payor_grouping]+[carrier_code]+[state]+[Collector_Name] as Extid
FROM [Table1]
WHERE [resp_ind] = 'Insurance'
GROUP BY [resp_ins]+[resp_payor_grouping]+[carrier_code]+[state]+[Collector_Name]) B
ON A.[resp_ins]+A.[resp_payor_grouping]+A.[carrier_code]+A.[state]+A.[Collector_Name] = B.[resp_ins]+B.[resp_payor_grouping]+B.[carrier_code]+B.[state]+B.[Collector_Name];
My ON and Group By statements are eventually the primary key in new table.
Your alias B hasn't columns as you mentioned. It has just on column Extid.
SELECT DISTINCT A.[carrier_code],[carrier_name], [carrier_grouping], A.[collector_name], [dataset_loaded], [docnum], [envoy_payer_id], [loc], [market], [master_payor_grouping], [plan_class], [plan_name], A.[resp_ins],A.[resp_ind], A.[resp_payor_grouping], A.[Resp_Plan_Type], A.[rspphone], A.[state], A.[sys],A.[resp_ins]+A.[resp_payor_grouping]+A.[carrier_code]+A.[state]+A.[Collector_Name] as ExtId
FROM [Table1] A
INNER JOIN
(SELECT [resp_ins]+[resp_payor_grouping]+[carrier_code]+[state]+[Collector_Name] as Extid
FROM [Table1]
WHERE [resp_ind] = 'Insurance'
GROUP BY [resp_ins]+[resp_payor_grouping]+[carrier_code]+[state]+[Collector_Name]) B
ON A.[resp_ins]+A.[resp_payor_grouping]+A.[carrier_code]+A.[state]+A.[Collector_Name] = B.Extid;
Try this, I didn't put all the column in result, you can manage yourself.
select A.*
from
(
select [carrier_code],[carrier_name], [sys],[resp_ins]+[resp_payor_grouping]+[carrier_code]+[state]+[Collector_Name] as ExtId
FROM [Table1]
) A
inner join
(
select distinct Extid
from
(
SELECT [resp_ins]+[resp_payor_grouping]+[carrier_code]+[state]+[Collector_Name] as ExtId
FROM [Table1]
WHERE [resp_ind] = 'Insurance'
) ins
) B on (A.ExtId = B.ExtId)
You don't need to concatenate the values - you can GROUP BY and JOIN on multiple columns.
SELECT DISTINCT
...
FROM
[Table1] A
INNER JOIN
(
SELECT
[resp_ins],
[resp_payor_grouping],
[carrier_code],
[state],
[Collector_Name]
FROM
[Table1]
WHERE
[resp_ind] = 'Insurance'
GROUP BY
[resp_ins],
[resp_payor_grouping],
[carrier_code],
[state],
[Collector_Name]
) B
ON
(
A.[resp_ins] = B.[resp_ins]
Or
(A.[resp_ins] Is Null And B.[resp_ins] Is Null)
)
And
(
A.[resp_payor_grouping] = B.[resp_payor_grouping]
Or
(A.[resp_payor_grouping] Is Null And B.[resp_payor_grouping] Is Null)
)
And
(
A.[carrier_code] = B.[carrier_code]
Or
(A.[carrier_code] Is Null And B.[carrier_code] Is Null)
)
And
(
A.[state] = B.[state]
Or
(A.[state] Is Null And B.[state] Is Null)
)
And
(
A.[Collector_Name] = B.[Collector_Name]
Or
(A.[Collector_Name] Is Null And B.[Collector_Name] Is Null)
)
;

How to perform a LEFT JOIN in SQL Server between two SELECT statements?

I have two SELECT statements in SQL Server like these:
(SELECT [UserID] FROM [User])
(SELECT [TailUser], [Weight] FROM [Edge] WHERE [HeadUser] = 5043)
I want to perform a LEFT JOIN between these two SELECT statements on [UserID] attribute and [TailUser] attribute. I want to join existent records in second query with the corresponding records in first query and NULL value for absent records. How can I do this?
SELECT * FROM
(SELECT [UserID] FROM [User]) a
LEFT JOIN (SELECT [TailUser], [Weight] FROM [Edge] WHERE [HeadUser] = 5043) b
ON a.UserId = b.TailUser
SELECT [UserID] FROM [User] u LEFT JOIN (
SELECT [TailUser], [Weight] FROM [Edge] WHERE [HeadUser] = 5043) t on t.TailUser=u.USerID
select *
from user
left join edge
on user.userid = edge.tailuser
and edge.headuser = 5043
Try this:
SELECT user.userID, edge.TailUser, edge.Weight
FROM user
LEFT JOIN edge ON edge.HeadUser = User.UserID
WHERE edge.HeadUser=5043
OR
AND edge.HeadUser=5043
instead of a WHERE clause.