Need help fixing the syntax for this LEFT OUTER JOIN - sql

I have a database structure like so:
SELECT * FROM Culture;
------------------------
Id ShortName FullName Supported
22 en-US English (United States) 1
23 fr-FR French (France) 1
24 hi-IN Hindi (India) 0
SELECT * FROM ResourceKey;
----------------------------
Id Name
20572 HowAreYou
20571 Hello
20573 ThisKeyHasUSEnglishValueOnly
SELECT * FROM Strings;
-----------------------
Id CultureId ResourceKeyId ResourceValue
41133 22 20571 Hello
41134 22 20572 How are you?
41135 23 20571 Bonjour
41136 23 20572 Comment allez-vous?
41137 22 20573 This key has US English value only.
SELECT * FROM Category;
------------------------
Id Name
1 JavaScript
SELECT * FROM StringCategory;
------------------------------
Id ResourceKeyId CategoryId
1 20571 1
2 20572 1
3 20573 1
I want to display all resource key names and resource values, i.e. string values against each key, for, say, the French (France) culture, i.e. the culture with the ShortName fr-FR but even if a key does not have a value in the culture, it must display the key name but NULL for the value. Like so:
Name ResourceValue
-------------------------------------------------------
Hello Bonjour
HowAreYou Comment allez-vous?
ThisKeyHasUSEnglishValueOnly NULL
It seems like a simple LEFT OUTER JOIN application to me, but my code isn't working. Could someone please help correct my code?
My query is:
SELECT ResourceKey.Name AS Name, ResourceValue
FROM
ResourceKey LEFT OUTER JOIN Strings
ON
Strings.ResourceKeyId = ResourceKey.Id
INNER JOIN StringCategory
ON
StringCategory.ResourceKeyId = Strings.ResourceKeyId
INNER JOIN Category
ON
StringCategory.CategoryId = Category.Id
LEFT OUTER JOIN Culture
ON
Strings.CultureId = Culture.Id AND Culture.Id = (SELECT Id FROM Culture WHERE ShortName = 'fr-FR')
AND
Category.Name = 'JavaScript';
Somehow, the last join in the above-query turns out to become an inner join, eliminating those rows where there is no value in the said culture.

SELECT a.name, b.ResourceValue
FROM ResourceKey a
LEFT JOIN
(
SELECT b.ResourceKeyID, b.ResourceValue
FROM Strings b
INNER JOIN Culture c
ON b.CultureID = c.ID
WHERE c.shortname = 'fr-FR'
) b ON a.ID = b.ResourceKeyId
UPDATED
USE SSTOBMAY;
SELECT a.name, b.ResourceValue
FROM ResourceKey a
LEFT JOIN
(
SELECT b.ResourceKeyID, b.ResourceValue
FROM Strings b
INNER JOIN Culture c
ON b.CultureID = c.ID
WHERE c.shortname = 'fr-FR'
) b ON a.ID = b.ResourceKeyId
INNER JOIN
StringCategory sc ON
sc.ResourceKeyId = a.Id
INNER JOIN Category c ON c.Id = sc.CategoryId
WHERE c.Name = 'JavaScript';
SQLFiddle Demo

LEFT JOINS can become inner joins when you specify criteria on the outer joined table .
Try using a Left join to a subquery of culture containing your where clause instead of left joining to Culture.
LEFT JOIN (SELECT Id ,resourcevalue
FROM Culture
WHERE shortname = 'fr-FR') as CULTURE
ON
Strings.CultureId = Culture.Id AND Culture.Id
Full query
SELECT ResourceKey.Name AS Name, ResourceValue
FROM
ResourceKey LEFT OUTER JOIN Strings
ON
Strings.ResourceKeyId = ResourceKey.Id
INNER JOIN StringCategory
ON
StringCategory.ResourceKeyId = Strings.ResourceKeyId
INNER JOIN Category
ON
StringCategory.CategoryId = Category.Id
LEFT JOIN (SELECT Id ,resourcevalue
FROM Culture
WHERE shortname = 'fr-FR') as CULTURE
ON
Strings.CultureId = Culture.Id
WHERE Category.Name = 'JavaScript';

Related

Getting extra Row containing Null Value for specific Names

In my Query if CompanyName has Coamount = NULL then Final should be as of Contract amount. If CompanyName has Coamount then Final would be ContractAmount + Coamount.
I am getting all these answers but the query is also returning me rows which has NULL value in Coamount for those company name in which coamount is already present.
for eg: Row1, why is that row coming when I am getting row 2 as my answer according to my query.
Here is the code:
SELECT DISTINCT
HBRegions.RegionName,PropertyGroups.Name AS Owner,Properties.EntityID, Properties.Address,Vendors.CompanyName,
SubContractorDrawDetails.InvoiceUploadDate,SubContractorDrawDetails.InvoiceAmount,SubContractorDrawDetails.PaymentDate,
LienWaivers.FinalLienWaiverRcvdDate,SubContractorDrawDetails.PaymentAmount, subcontractors.ContractAmount,cc.Coamount ,
(subcontractors.ContractAmount + cc.Coamount ) AS ActualContractAmount,
case when cc.Coamount is null then SubContractors.ContractAmount
when CC.Coamount is not null then (subcontractors.ContractAmount + cc.Coamount ) end as Final
FROM Users inner JOIN
Vendors ON Users.UserId = Vendors.UserID inner JOIN
LienWaivers ON Users.UserId = LienWaivers.UserID inner JOIN
Constructions ON LienWaivers.ConstructionID = Constructions.ConstructionId inner JOIN
Properties ON Constructions.HBId = Properties.HBId inner JOIN
ChangeOrderDetails ON Constructions.ConstructionId = ChangeOrderDetails.ConstructionId left JOIN
ChangeOrderLineItems ON Users.UserId = ChangeOrderLineItems.SubContractorId AND
ChangeOrderDetails.ChangeOrderId = ChangeOrderLineItems.ChangeOrderId
left join
(select sum(ChangeOrderDetails.ChangeOrderApprovedAmountContractor) as Coamount, ChangeOrderLineItems.SubContractorId,Constructions.ConstructionId
from ChangeOrderDetails inner join ChangeOrderLineItems
on ChangeOrderDetails.ChangeOrderId = ChangeOrderLineItems.ChangeOrderId
inner join Users on ChangeOrderLineItems.SubContractorId = Users.UserId
left join Constructions on Constructions.ConstructionId = ChangeOrderDetails.ConstructionId
-- left join Properties on Properties.HBId = Constructions.HBId
where ChangeOrderDetails.ChangeOrderApprovedAmountContractor is not null
group by ChangeOrderLineItems.SubContractorId,Constructions.ConstructionId
) AS cc on cc.SubContractorId = ChangeOrderLineItems.SubContractorId and cc.ConstructionId = Constructions.ConstructionId
inner join HBRegions ON Properties.RegionId = HBRegions.RegionID inner JOIN
PropertyGroups ON Properties.PropertyGroup = PropertyGroups.PropertyGroupId
inner join SubContractors ON Users.UserId = SubContractors.UserID AND Properties.HBId = SubContractors.HBId
inner join SubContractorDrawDetails ON SubContractors.SubContractorId = SubContractorDrawDetails.SubContractorId
WHERE (Properties.Address = '470 ROYCROFT BLVD BUFFALO NY 14225')[enter image description here][1]

Join on TOP 1 from subquery while referencing outer tables

I am starting with this query, which works fine:
SELECT
C.ContactSys
, ... a bunch of other rows...
FROM Users U
INNER JOIN Contacts C ON U.ContactSys = C.ContactSys
LEFT JOIN UserWatchList UW ON U.UserSys = UW.UserSys
LEFT JOIN Accounts A ON C.AccountSys = A.AccountSys
WHERE
C.OrganizationSys = 1012
AND U.UserTypeSys = 2
AND C.FirstName = 'steve'
Now, I've been given this requirement:
For every visitor returned by the Visitor Search, take ContactSys, get the most recent entry in the GuestLog table for that contact, then return the columns ABC and XYZ from the GuestLog table.
I'm having trouble with that. I need something like this (I think)...
SELECT
C.ContactSys
, GL.ABC
, GL.XYZ
, ... a bunch of other rows...
FROM Users U
INNER JOIN Contacts C ON U.ContactSys = C.ContactSys
LEFT JOIN UserWatchList UW ON U.UserSys = UW.UserSys
LEFT JOIN Accounts A ON C.AccountSys = A.AccountSys
LEFT JOIN (SELECT TOP 1 * FROM GuestLog GU WHERE GU.ContactSys = ????? ORDER BY GuestLogSys DESC) GL ON GL.ContactSys = C.ContactSys
WHERE
C.OrganizationSys = 1012
AND U.UserTypeSys = 2
AND C.FirstName = 'steve'
Only that's not it because that subquery on the JOIN doesn't know anything about the outer tables.
I've been looking at these posts and their answers, but I'm having a hard time translating them to my needs:
SQL: Turn a subquery into a join: How to refer to outside table in nested join where clause?
Reference to outer query in subquery JOIN
Referencing outer query in subquery
Referencing outer query's tables in a subquery
If that is the logic you want, you can use OUTER APPLY:
SELECT C.ContactSys, GL.ABC, GL.XYZ,
... a bunch of other columns ...
FROM Users U JOIN
Contacts C
ON U.ContactSys = C.ContactSys LEFT JOIN
UserWatchList UW
ON U.UserSys = UW.UserSys LEFT JOIN
Accounts A
ON C.AccountSys = A.AccountSys OUTER APPLY
(SELECT TOP 1 gl.*
FROM GuestLog gl
WHERE gl.ContactSys = C.ContactSys
ORDER BY gl.GuestLogSys DESC
) GL
WHERE C.OrganizationSys = 1012 AND
U.UserTypeSys = 2 AND
C.FirstName = 'steve'

SQL count in select query

I have a sql query that creates a label in a cab file for a shopping company. I want to include the amount of packages in an order, some have multiple.
Each returns line in my select query has an I’d and contains a package but I need to count them.
So I have:
Name Email Weight Price ID
Joe B J#.com 10 12.5. 1
Joe B J#.com 10 12.5. 1
Joe C JC#.com 10 14.5. 2
How can I count the ID’s to return a column called pieces and in this example it would be 2 for ID 1 and 1 for ID 2
Thanks
James
enter code here
Select
'WPX' As 'Product Code',
delivery_header.dh_datetime As 'Shipment Date',
'G' As 'Shipment Type',
order_header_detail.ohd_delivery_email As 'Receiver Email Address',
variant_detail.vad_weight As 'Shipment Weight in KG',
(lots of other fields....)
delivery_header.dh_number As 'Shippers Reference',
(SELECT Count(*)
FROM delivery_header
WHERE
dh_number = OU.dh_number
) As 'Number of Pieces',
From delivery_line_item Inner Join
delivery_header On delivery_header.dh_id = delivery_line_item.dli_dh_id
Inner Join
order_line_item On delivery_line_item.dli_oli_id = order_line_item.oli_id
Inner Join
variant_detail On variant_detail.vad_id = order_line_item.oli_vad_id
Inner Join
order_header On order_header.oh_id = order_line_item.oli_oh_id Inner Join
stock_location On stock_location.sl_id = order_line_item.oli_sl_id Inner Join
customer_detail On customer_detail.cd_id = order_header.oh_cd_id Inner Join
order_header_detail On order_header.oh_id = order_header_detail.ohd_oh_id
Left Join
order_header_analysis On order_header.oh_id = order_header_analysis.oha_oh_id
Left Join
order_customer_analysis On order_header.oh_id =
order_customer_analysis.oca_oh_id Left Join
order_delivery_analysis On order_header.oh_id =
order_delivery_analysis.oda_oh_id Left Join
order_line_analysis On order_line_item.oli_id = order_line_analysis.ola_oli_id
Left Join
order_line_product_analysis On order_line_item.oli_id =
order_line_product_analysis.olpa_oli_id Left Join
order_line_variant_analysis On order_line_item.oli_id =
order_line_variant_analysis.olva_oli_id Inner Join
product_detail On product_detail.pd_id = variant_detail.vad_pd_id Inner Join
delivery_method On delivery_method.dm_id = order_header_detail.ohd_dm_id
Inner Join
delivery_method [Delivery Method] On [Delivery Method].dm_id =
order_header_detail.ohd_dm_id Inner Join
currency On currency.c_id = order_header.oh_c_id And currency.c_id =
delivery_method.dm_c_id And currency.c_id = [Delivery Method].dm_c_id
Where
delivery_header.dh_number IN (199364,199363,199362,199360)
Order By delivery_header.dh_number
You can use GROUP BY with COUNT like this:
SELECT ID, COUNT(*) as count FROM tbl GROUP BY ID
What I understood from your question is that, you are looking for output like
Name Email Weight Price ID Pieces
Joe B J#.com 10 12.5. 1 2
Joe B J#.com 10 12.5. 1 2
Joe C JC#.com 10 14.5. 2 1
Using following query you should get the desired output in most of the DBMS.
SELECT NAME,
EMAIL,
WEIGHT,
PRICE,
ID,
(SELECT Count(*)
FROM <YOUR_TABLE_NAME>
WHERE ID= OU.ID) AS Pieces
FROM <YOUR_TABLE_NAME> OU
Similar Query for MS SQL Server can be
SELECT NAME, EMAIL,WEIGHT , Price, ID,CT.Pieces
FROM <YOUR_TABLE_NAME> OU
CROSS APPLY
(
SELECT COUNT(*) AS Pieces FROM <YOUR_TABLE_NAME> IU WHERE OU.ID=IU.ID
)CT

SQL Filtering rows with no duplicate value

Hi so I'm new to SQL and I'm trying to find a way in which I can obtain only the rows that have values that are not duplicate to each other in a specific column of table.
For example the Table below is called T1 and contains:
ID|Branch ID
1 444
2 333
3 444
4 111
5 555
6 333
The result I want will be
ID|Branch ID
4 111
5 555
So only showing non duplicate rows
Edit: I want to apply this to a large relational code. Here is a snippet of where I want it to be added
FROM dbo.LogicalLine
INNER JOIN dbo.Page ON dbo.LogicalLine.page_id = dbo.Page.id
INNER JOIN dbo.Branch ON dbo.LogicalLine.branch_id = dbo.Branch.id
The table LogicalLine will have a column called branch_id containing duplicate id values. I wish to filter those out showing only the non-duplicate branch_id like above example then INNER JOIN the Branch table into the LogicalLine which I have done.
Added -Full Code here:
SELECT
(SELECT name
FROM ParentDevice
WHERE (Dev1.type NOT LIKE '%cable%') AND (id = Dev1.parent_device_id))T1_DeviceID,
(SELECT name
FROM Symbol
WHERE (id = CP1.symbol_id) AND (type NOT LIKE '%cable%'))T1_DeviceName,
(SELECT name
FROM Location
WHERE (id = Page.location_id))T1_Location,
(SELECT name
FROM Installation
WHERE (id = Page.installation_id))T1_Installation,
(SELECT name
FROM ParentDevice
WHERE (Dev2.type NOT LIKE '%cable%') AND (id = Dev2.parent_device_id))T2_DeviceID,
(SELECT name
FROM Symbol
WHERE ( id = CP2.symbol_id) AND (type NOT LIKE '%cable%'))T2_DeviceName,
(SELECT name
FROM Location
WHERE (id = PD2.location_id))T2_Location,
(SELECT name
FROM Installation
WHERE (id = Page.installation_id))T2_Installation,
(SELECT devicefamily
FROM Device
WHERE (type LIKE '%cable%') AND (id = SymCable.device_id))CablePartNumber,
(SELECT name
FROM ParentDevice
WHERE (id = DevCable.parent_device_id) AND (DevCable.type LIKE '%cable%'))CableTag
FROM dbo.LogicalLine
INNER JOIN dbo.Page ON dbo.LogicalLine.page_id = dbo.Page.id
INNER JOIN dbo.Branch ON dbo.LogicalLine.branch_id = dbo.Branch.id
LEFT OUTER JOIN dbo.Symbol AS SymCable ON dbo.LogicalLine.cable_id = SymCable.id
LEFT OUTER JOIN dbo.Device AS DevCable ON SymCable.device_id = DevCable.id
LEFT OUTER JOIN dbo.ParentDevice AS ParentCable ON DevCable.parent_device_id = ParentCable.id
INNER JOIN dbo.SymbolCP AS CP1 ON dbo.Branch.cp1_id = CP1.id
INNER JOIN dbo.SymbolCP AS CP2 ON dbo.Branch.cp2_id = CP2.id
INNER JOIN dbo.Symbol AS S1 ON CP1.symbol_id = S1.id
INNER JOIN dbo.Symbol AS S2 ON CP2.symbol_id = S2.id
INNER JOIN dbo.Device AS Dev1 ON S1.device_id = Dev1.id
INNER JOIN dbo.Device AS Dev2 ON S2.device_id = Dev2.id
INNER JOIN dbo.ParentDevice AS PD1 ON Dev1.parent_device_id = PD1.id
INNER JOIN dbo.ParentDevice AS PD2 ON Dev2.parent_device_id = PD2.id
INNER JOIN dbo.Location AS L1 ON PD1.location_id = L1.id
INNER JOIN dbo.Location AS L2 ON PD2.location_id = L2.id
INNER JOIN dbo.Installation AS I1 ON L1.installation_id = I1.id
INNER JOIN dbo.Installation AS I2 ON L2.installation_id = I2.id
WHERE
(PD1.project_id = #Projectid) AND (dbo.LogicalLine.drawingmode LIKE '%Single Line%');
Select Id, BranchId from table t
Where not exists
(Select * from table
where id != t.Id
and BranchId = t.BranchId)
or
Select Id, BranchId
From table
Group By BranchId
Having count(*) == 1
EDIT: to modify as requested, simply add to your complete SQL query a Where clause:
Select l.Id BranchId, [plus whatever else you have in your select clause]
FROM LogicalLine l
join Page p ON p.id = l.page_Id
join Branch b ON b.Id = l.branch_id
Group By l.branch_id, [Plus whatever else you have in Select clause]
Having count(*) == 1
or
Select l.Id BranchId, [plus whatever else you have in your select clause]
FROM LogicalLine l
join Page p on p.id = l.page_Id
join Branch b on b.Id = l.branch_id
Where not exists
(Select * from LogicalLine
where id != l.Id
and branch_id = l.branch_id)

SQL Counting # of times a member shows up with certain code values

I am running a query that returns the location of a member and the product the member is enrolled in. Each time a member makes a claim with their product, they get a revenue code associated to them. Below is my query that I have now:
SELECT DISTINCT
e.State,
f.Product,
d.MemberID,
b.RevenueCode
FROM
Claims a
INNER JOIN
dw.Revenue b
ON
a.RevenueKey = b.RevenueKey
INNER JOIN
dw.Member d
ON
a.MemberKey = d.MemberKey
INNER JOIN
dw.Product f
ON
a.ProductKey = f.ProductKey
INNER JOIN
dw.State
ON
a.StateKey = f.StateKey
WHERE
b.RevenueCode IN ('0134', '0135')
It returns a set like the following:
State Product MemberID RevenueCode
MN xxx 945-234-245 0134
MN xxx 945-234-245 0135
SD xxx 231-345-235 0134
When a MemberID has both 0134 and 0135 RevenueCodes associated with it, they are considered to be in a special category. How would I modify my above query to count the number of times a MemberID has both RevenueCodes by State and by Product?
SELECT DISTINCT
e.State
,f.Product
,d.MemberID
,b.RevenueCode
,(SELECT 1
FROM Claims AS a1
INNER JOIN dw.Revenue AS b1 ON a1.RevenueKey = b1.RevenueKey
WHERE b1.RevenueCode IN ('0134', '0135')
AND b.revenuekey = b1.revenuekey
AND a.MemberKey = a1.Memberkey
HAVING COUNT(DISTINCT b1.RevenueCode) = 2) AS SpecialCategory
FROM Claims a
INNER JOIN dw.Revenue b ON a.RevenueKey = b.RevenueKey
INNER JOIN dw.Member d ON a.MemberKey = d.MemberKey
INNER JOIN dw.Product f ON a.ProductKey = f.ProductKey
INNER JOIN dw.State ON a.StateKey = f.StateKey
WHERE b.RevenueCode IN ('0134', '0135')
SELECT DISTINCT
e.State,
f.Product,
d.MemberID,
b.RevenueCode.
CASE WHEN EXISTS(
SELECT NULL
FROM Claims a1
JOIN dw.Revenue b1 ON a1.RevenueKey = b1.RevenueKey
JOIN dw.Member d1 ON a1.MemberKey = d1.MemberKey
JOIN dw.Product f1 ON a1.ProductKey = f1.ProductKey
WHERE b1.RevenueCode IN('0134', '0135') AND
d1.MemberID = d.MemberID AND
f1.ProductKey = f.ProductKey AND
f1.StateKey = f.StateKey
) THEN 1 ELSE 0 END As IsSpecialCategory
FROM
...
Figured it out...Simply needed to Count the Distinct RevenueCodes and Group By State, Product, and MemberID