Inner join tables - sql

I have SQL table Policy that contains column as PolicyNumber which has value 'CCL-9997-10497'
and another table PolicyImages which also has column PolicyNumber which has value 'CCL-9997-000010497'
I wanted to inner join both these table on PolicyNumber ?
How can I achieve it ?

Your two tables have different format of PolicyNumber so you need some kind of computation.
I think below query will help you
SELECT a.* FROM
FROM Table1 a INNER JOIN Table1 b ON a.PolicyNumber =
Replace(b.PolicyNumber,'-' + right(b.PolicyNumber,charindex('-',REverse(b.PolicyNumber))-1),
'-' + convert(varchar,Convert(Decimal,right(b.PolicyNumber,charindex('-',REverse(b.PolicyNumber))-1)))
)

This should do it:
SELECT *
FROM Policy
INNER JOIN PolicyImageq ON Policy.PolicyNumber = PolicyImages.PolicyNumber

If this is a one-time mistake, then you can do:
Policy p join
PolicyImages pi
on p.PolicyNumber = pi.PolicyNumber or
(p.PolicyNumber = 'CCL-9997-10497' and pi.PolicyNumber = 'CCL-9997-000010497')
If this is a formatting issue, then the solution is actually database-specific.

Related

Why is it not matching?

Code:
(SELECT
[QBDATABASE].[dbo].[itemnoninventory].[FullName],
[LotTracker].[dbo].[tblParts].[PartNo],
[QBDATABASE].[dbo].[itemnoninventory].[CustomField2] AS StdCost,
[QBDATABASE].[dbo].[salesorpurchasedetail].[Price],
[QBDATABASE].[dbo].[itemnoninventory].[ListID],
[QBDATABASE].[dbo].[salesorpurchasedetail].[IDKEY]
FROM
[QBDATABASE].[dbo].[itemnoninventory]
Inner JOIN
[QBDATABASE].[dbo].[salesorpurchasedetail] ON [QBDATABASE].[dbo].[itemnoninventory].[ListID] = [QBDATABASE].[dbo].[salesorpurchasedetail].[IDKEY]
INNER JOIN
[LotTracker].[dbo].[tblParts] ON [QBDATABASE].[dbo].[itemnoninventory].[FullName] like [LotTracker].[dbo].[tblParts].[PartNo]
WHERE ([QBDATABASE].[dbo].[salesorpurchasedetail].[AccountRef_FullName] = 'Inventory, Raw Material')
I added unneeded selects to create the screenshot below of sample results.
ListID is varchar(255), null)
IDKEY is varchar(255), null)
Questions:
What would cause query to not see ListID = IDKEY for the NULL results?
EDIT Goal:
Stdcost should match the Price amount if ListID=IDKEY and FullName=PartNo
This isn't an answer but too long for a comment. Here your exact same query. The ONLY changes I made was a little formatting and removed all those horrifically long object names and used aliases instead.
SELECT
ini.FullName,
p.PartNo,
ini.CustomField2 AS StdCost,
spd.Price,
ini.ListID,
spd.IDKEY
FROM QBDATABASE.dbo.itemnoninventory ini
Inner JOIN QBDATABASE.dbo.salesorpurchasedetail spd ON ini.ListID = spd.IDKEY
INNER JOIN LotTracker.dbo.tblParts p ON ini.FullName like p.PartNo
WHERE spd.AccountRef_FullName = 'Inventory, Raw Material'
The answer to your question is that the row in itemnoninventory contain NULL so of course it will be NULL in the query.
After your edit, you need to have the price returned if CustomField2 is null. This can be done with either ISNULL or COALESCE. ISNULL will return the second value if the first value is null.
(SELECT
[QBDATABASE].[dbo].[itemnoninventory].[FullName],
[LotTracker].[dbo].[tblParts].[PartNo],
ISNULL([QBDATABASE].[dbo].[itemnoninventory].[CustomField2],[QBDATABASE].[dbo].[salesorpurchasedetail].[Price]) AS StdCost,
[QBDATABASE].[dbo].[salesorpurchasedetail].[Price],
[QBDATABASE].[dbo].[itemnoninventory].[ListID],
[QBDATABASE].[dbo].[salesorpurchasedetail].[IDKEY]
FROM
[QBDATABASE].[dbo].[itemnoninventory]
Inner JOIN
[QBDATABASE].[dbo].[salesorpurchasedetail] ON [QBDATABASE].[dbo].[itemnoninventory].[ListID] = [QBDATABASE].[dbo].[salesorpurchasedetail].[IDKEY]
INNER JOIN
[LotTracker].[dbo].[tblParts] ON [QBDATABASE].[dbo].[itemnoninventory].[FullName] like [LotTracker].[dbo].[tblParts].[PartNo]
WHERE ([QBDATABASE].[dbo].[salesorpurchasedetail].[AccountRef_FullName] = 'Inventory, Raw Material')
I cannot upvote. I combined both seans replies and have what I wanted. Ty both.
SELECT
ini.FullName,
p.PartNo,
ISNULL(ini.CustomField2,spd.Price) AS StdCost,
spd.Price,
ini.ListID,
spd.IDKEY
FROM QBDATABASE.dbo.itemnoninventory ini
Inner JOIN QBDATABASE.dbo.salesorpurchasedetail spd ON ini.ListID = spd.IDKEY
INNER JOIN LotTracker.dbo.tblParts p ON ini.FullName like p.PartNo
WHERE spd.AccountRef_FullName = 'Inventory, Raw Material'

SQL query to return unique top row for each group

Trying to write a query that would return a unique record for each systems name.
The existing query returns several records for each systemName since there are multiple version of the same product present.
I am able to sort by version number but would like to be able to only keep the top version number for each system.
SELECT DISTINCT v.sysName
,v.groupName
,a.versionNumb
,b.userName
FROM table1 AS a
INNER JOIN table2 AS v ON v.sID = a.sID
INNER JOIN table3 AS b ON v.sID = b.sID
WHERE a.versionNumb LIKE '10.%'
AND v.groupName LIKE '%' + #groupVar
ORDER BY a.versionNumb DESC
Tried using ROW_NUMBER() to sort and return the row value but I'm still not 100% on getting the proper data extracted.
Any help would be appreciated!
Just use MAX() and GROUP BY:
SELECT v.sysName,
v.groupName,
MAX(a.versionNumb) as versionNumb,
b.userName
FROM table1 AS a
INNER JOIN table2 AS v ON v.sID = a.sID
INNER JOIN table3 AS b ON v.sID = b.sID
WHERE a.versionNumb LIKE '10.%'
AND v.groupName LIKE '%' + #groupVar
GROUP BY v.sysName, v.groupName, b.userName
I removed your DISTINCT because it's redundant with a GROUP BY
You can use a query to GROUP BY by system name and after JOIN to take all information you need
SELECT d.sysName, max (d.versionNumb)
FROM (select * from table1 AS a
INNER JOIN table2 AS v ON v.sID = a.sID) as d
Group by d.sysName

SQL View statement with 2 INNER JOINS

Can anyone help me with this issue I tried many times but still haven't found the solution
Here is the original View that I have in my database but now I made changes in the database and the view need to be changed also.
Here is the view as it was:
SELECT
[tableN].*,
[tabB].[att1] AS tabB_email, [tabB].[name] AS tabB_name,
[tabC].[name] AS tabC_name
FROM
[tabC]
INNER JOIN
([tableN]
INNER JOIN [tabB] ON [tableN].[sender_id] = [tabB].[ID])
ON [tabC].[ID] = [tableN].[recipient_id]
Here is what is the difficult point for me. Now I don't have this 2 tables tabB and tabC
They are now in one table tabX and have an identifier field roleId. I manage to get all the columns except the last one [tabC].[name] AS tabC_name
Any ideas?
Try like this
SELECT [tableN].*, [tabX].[att1] AS tabB_email, [tabX].[name] AS tabB_name,
t1.[name] AS tabC_name
FROM [tabX] as t INNER JOIN ([tableN] INNER JOIN [tabX]
ON [tableN].[sender_id] = [tabX].[roleid])
ON t.[roleid] = [tableN].[recipient_id]
SELECT [tableN].*, [Tabx] .[att1] AS tabB_email, [Tabx] .[name] AS tabB_name
FROM [Tabx] A
INNER JOIN [TABLEN] B
ON A.ROLEID=B.RECIPIENT_ID
SELECT [TableN].*, Bd.[email] AS bd_email, Bd.[showname] AS bd_name,
Pc.[showname] AS pc_name
FROM
[TABLE_X] AS Pc
INNER JOIN ([TableN]
INNER JOIN [TABLE_X] AS Bd
ON [TableN].[sender_id] = Bd.[ID] AND Bd.roleID = 1)
ON Pc.[ID] = [TableN].[recipient_id] AND Pc.roleID = 2
I finally find the the code that is working as needed

Join different tables depending on field values

I have the following sql view result which contains the audited changes for every field for every table in the system:
In this case the above image tell us that both read and write permissions were revoked for the user Lucas for the subscription called MySubscription.
I need to display that info in a grid however that is not what I want to display, I mean, I donĀ“t want to display IDs. I need to display "Read" instead of 50, "Write" instead of 51, "Lucas" instead of 1 and "MySubscription" instead of 6.
To do that I would like to improve the sql view to get the values instead of their IDs as I mention above. The result that I am looking for is this one:
The database contains the tables Subscriptions, ProductPermissions and TenantUsers to get the needed info using joins.
Could you please give me some clues about how could I achieve what I need? Thank you.
You could do this with a series of LEFT JOINs, some casting might be required to get the datatype of the joining column the same as NewValue (I've assumed a column called Name in all your joining tables, this may need changing):
SELECT a.AuditLogId,
a.Operation,
a.[Table],
a.RowId,
a.Name,
[OldValue] = COALESCE(s_Old.Name, pp_old.Name, t_Old.Name),
[NewValue] = COALESCE(s_New.Name, pp_New.Name, t_New.Name)
FROM AuditLog a
LEFT JOIN Subscriptions s_Old
ON a.OldValue = CAST(s_Old.SubscriptionID AS VARCHAR)
AND a.Name = 'SubscriptionID'
LEFT JOIN ProductPermissions pp_Old
ON a.OldValue = CAST(p_Old.ProductPermissionID AS VARCHAR)
AND a.Name = 'ProductPermissionId'
LEFT JOIN TenantUsers t_Old
ON a.OldValue = CAST(t_Old.TenantUserId AS VARCHAR)
AND a.Name = 'TenantUsers'
LEFT JOIN Subscriptions s_New
ON a.NewValue = CAST(s_New.SubscriptionID AS VARCHAR)
AND a.Name = 'SubscriptionID'
LEFT JOIN ProductPermissions pp_New
ON a.NewValue = CAST(p_New.ProductPermissionID AS VARCHAR)
AND a.Name = 'ProductPermissionId'
LEFT JOIN TenantUsers t_New
ON a.NewValue = CAST(t_New.TenantUserId AS VARCHAR)
AND a.Name = 'TenantUsers'
If required you could then PIVOT this into one row per transaction:
SELECT a.AuditLogId,
a.Operation,
a.[Table],
a.RowId,
[OldSubscriptionValue] = MAX(s_old.Name),
[OldProductPermissionValue] = MAX(pp_old.Name),
[OldTennantUserValue] = MAX(t_old.Name),
[NewSubscriptionValue] = MAX(s_New.Name),
[NewProductPermissionValue] = MAX(pp_New.Name),
[NewTennantUserValue] = MAX(t_New.Name)
FROM AuditLog a
LEFT JOIN Subscriptions s_Old
ON a.OldValue = CAST(s_Old.SubscriptionID AS VARCHAR)
AND a.Name = 'SubscriptionID'
LEFT JOIN ProductPermissions pp_Old
ON a.OldValue = CAST(p_Old.ProductPermissionID AS VARCHAR)
AND a.Name = 'ProductPermissionId'
LEFT JOIN TenantUsers t_Old
ON a.OldValue = CAST(t_Old.TenantUserId AS VARCHAR)
AND a.Name = 'TenantUsers'
LEFT JOIN Subscriptions s_New
ON a.NewValue = CAST(s_New.SubscriptionID AS VARCHAR)
AND a.Name = 'SubscriptionID'
LEFT JOIN ProductPermissions pp_New
ON a.NewValue = CAST(p_New.ProductPermissionID AS VARCHAR)
AND a.Name = 'ProductPermissionId'
LEFT JOIN TenantUsers t_New
ON a.NewValue = CAST(t_New.TenantUserId AS VARCHAR)
AND a.Name = 'TenantUsers'
GROUP BY a.AuditLogId, a.Operation, a.[Table], a.RowId;
It is a pretty dirty solution, I would be inclined to store this data in the format you want to select it in i.e. instead of 50/51, store read/write directly in the NewValue column.
Alternatively, if you did want the second format with one row per transaction then I'd be inclined to store it in this way. It could be worth reading about the Entity-Attribute-Value Antipattern.
You could PIVOT the data and LEFT JOIN to the lookup tables. Then UNPIVOT if necessary.
If you simply need to display words instead of numbers, create a lookup table that maps between the number and the word you want to display:
create table NewValueText (
NewValue integer,
Description char(20)
);
insert into NewValueText values
(50, 'Read'),
(51, 'Write'); --etc.
--MyTable is your table that contains the NewValue column.
select Description from MyTable
inner join NewValueText on MyTable.NewValue = NewValueText.NewValue;
You could try joining in your tables where your values are specific. You'll need to create a look-up table for other values other than Really it's a dirty solution because it means hard coding your NewValue fields into the SQL:
...
FROM
audit LEFT JOIN
mysubscription ON audit.rowid = mysubscription.tenantuserid
AND audit.newvalue = 1
LEFT JOIN
lookup_list ON audit.rowid = lookup_list.lookup_id
AND audit.newvalue <> 1
...
That may work for you.

Nested Select or Inner Join including rows from another table

I have a pretty complex select statement that returns counted statistics from tables (think of it as an answer bank -- the complex select statement below) using inner join.
These answers are related to a table called Questions_Bank_AnswerChoices (which stores all the questions).
I am attempting to first pull the Questions (from the table Questions_Bank_AnswerChoices) then match them up with the statistics (complex statement below). The complex statement below pulls the statistics, but does not pull the questions unless they have been answered.
So, if no one answers question1, then question one will not show up in the statistics because it is not included in the Answers table (bc no one answered it).
How can I achieve this? I think that I need to outer join?
Complex Select Statement:
WITH tbl as (
SELECT
Questions_Bank.QuestionID, Questions_Bank.QuestionName,
REPLACE(Schools_Answers_Items.AnswerValue, '? ', ', ') as AnswerValue,
COUNT(Schools_Answers_Items.SchoolsAnswersItemID) AS CountAnswer,
Schools_Answers_Items.SchoolID
FROM Questions_Bank
INNER JOIN Schools_Answers_Items
ON Questions_Bank.QuestionID = Schools_Answers_Items.QuestionID
LEFT OUTER JOIN Schools_Answers
ON Schools_Answers_Items.SchoolsAnswerID = Schools_Answers.SchoolsAnswerID
WHERE (Questions_Bank.QuestionID = 1108)
AND (Schools_Answers.SchoolID = 103)
GROUP BY
Schools_Answers_Items.SchoolID,
Schools_Answers_Items.AnswerValue,
Questions_Bank.QuestionID,
Questions_Bank.QuestionName
)
SELECT
QuestionID, QuestionName, AnswerValue, CountAnswer,
SUM(CountAnswer) OVER () AS CountAllAnswers
FROM tbl
Try changing this
INNER JOIN Schools_Answers_Items
ON Questions_Bank.QuestionID = Schools_Answers_Items.QuestionID
to
LEFT OUTER JOIN Schools_Answers_Items
ON Questions_Bank.QuestionID = Schools_Answers_Items.QuestionID
and you might want to remove this
AND (Schools_Answers.SchoolID = 103)
or replace it with this
AND (Schools_Answers.SchoolID = 103 OR Schools_Answers.SchoolID IS NULL)
Try this:
SELECT
Questions_Bank.QuestionID, Questions_Bank.QuestionName,
REPLACE(Schools_Answers_Items.AnswerValue, '? ', ', ') as AnswerValue,
Schools_Answers_Items.SchoolID
FROM Questions_Bank
LEFT OUTER JOIN Schools_Answers_Items
ON Questions_Bank.QuestionID = Schools_Answers_Items.QuestionID
LEFT OUTER JOIN Schools_Answers
ON Schools_Answers_Items.SchoolsAnswerID = Schools_Answers.SchoolsAnswerID
WHERE Schools_Answers_Items.SchoolID