LEFT JOIN two tables with multiple AND conditions - sql

I need help getting a sql statement correctly by joining two tables.
My goal is to return the number of purchases between certain purchase dates for given products where customer_id is null. The foreign key for table Purchases is prospect_id corresponding to id in Prospect
In separate SQL statements, I will have this:
SELECT COUNT (id) FROM Purchases
WHERE (purchasedate BETWEEN '5/1/18' AND '12/31/18')
AND (product = 'Scooter')
SELECT id
from Prospect
where customer_id is null
So, I am coming up with a query like this:
SELECT COUNT (id)
FROM Purchases
LEFT JOIN Prospect
ON Prospect.id = Purchases.prospect_id
AND (Purchases.purchasedate BETWEEN '5/1/18' AND '12/31/18')
AND Purchases.product = 'Scooter'
AND Prospect.customer_id is null;
but then I am getting ERROR: column reference "id" is ambiguous.

Use count(*):
SELECT COUNT(*)
FROM Purchases pu LEFT JOIN
Prospect pr
ON pr.id = pu.prospect_id AND
pr.customer_id is null
WHERE pu.purchasedate >= '2018-05-01' AND
pu.purchasedate < '2019-01-01' AND
pu.product = 'Scooter';
I made a few changes to the query.
First, the conditions on purchase are in the where clause rather than the on clause. Presumably, you actually want these to be filters.
Second, the dates use a proper format, YYYY-MM-DD.
I've also replaced the between with explicit comparisons. This means that the code works even when the "date" column has a time component.
Finally, I also introduced table aliases.

the reason for your error is that you did not define what table the "id" field you want to count is coming from.
SELECT
COUNT(PURCHASES.ID) AS PURCHASE_COUNT
FROM
Purchases
LEFT JOIN Prospect
ON Prospect.id = Purchases.prospect_id
AND (Purchases.purchasedate BETWEEN '5/1/18' AND '12/31/18')
AND Purchases.product = 'Scooter'
AND Prospect.customer_id is null;

Related

Left Join on three tables in access with Group by

I have broken my head with syntax error response from Access Jet engine.
I have three tables.
First one "tblMstItem" is the master table for Item details contains two columns "colITemID" PK and "colItemName"
Second one "tblStocks" is the table where the purchases are maintained. This table has a column "colRQty" which keeps the quantity of the particular item purchased. "colItemID" FK from "tblMstItem"
Third one "tblSales" is the table where the sales are maintained. This table has a column "colSoldQty" which keeps the quantity of the particular item sold. "colItemID" FK from "tblMstItem"
Therefore "colItemID" is common in all the three tables and has links created.
My requirement is I need all the Items listed in the "tblMstItem" table columns are "colItemID" "colItemName" and if there is any item purchased or any item sold should be shown as sum of that particular item.
I have used Left Join shown in the following select statement but it always giving me an error message.
Select statement as follows:
SELECT
i.colItemID,
i.colItemName,
s.rqty,
n.soldqty
from tblMstItem i
left join
( select sum( colRQty ) as rqty from tblStocks group by colItemID ) s
on i.colItemID = s.colItemID
left join
( select sum( colSoldQty ) as soldqty from tblSales group by colItemID ) n
on i.colItemID=n.colItemID``
I tried the above given code with many different syntax but every time I get syntax error. It is making me to doubt do MS Access support three table joins, I am sure I am wrong.
See the error Message below
Table columns and table link shown below
I would be very thankful to get any help on this. Access sql please because this I am able to get results in SQL Server.
Thanks in Advance
MS Access has a picky syntax. For instance, joins need extra parentheses. So, try this:
select i.colItemID, i.colItemName,
s.rqty, n.soldqty
from (tblMstItem as i left join
(select colItemID, sum(colRQty ) as rqty
from tblStocks
group by colItemID
) as s
on i.colItemID = s.colItemID
) left join
(select colItemID, sum( colSoldQty ) as soldqty
from tblSales
group by colItemID
) as n
on i.colItemID = n.colItemID;
You also need to select colItemID in the subqueries.

SQL Query Creates Duplicated Results

My task is to produce a report that shows the on time delivery of products to consumers. In essence I have achieved this. However, as you will see only some of the data is accurate.
Here is our test case: we have a sales order number '12312.' This sales order has had 5 partial shipments made (200 pieces each). The result is shown below from our DUE_DTS table.
Due Dates table data
The following code gives me the information I need (excluding due date information) to show the packing details of the 5 shipments:
DECLARE #t AS TABLE (
CUSTNAME char(35),
SONO char(10),
INVDATE date,
PACKLISTNO char(10),
PART_NO char(25),
SOBALANCE numeric(9,2)
)
INSERT INTO #t
SELECT DISTINCT c.CUSTNAME, s.SONO, p.INVDATE, p.PACKLISTNO, i.PART_NO, q.SOBALANCE
FROM [manex].[dbo].[SODETAIL]
INNER JOIN [manex].[dbo].[SOMAIN] s ON s.SONO = SODETAIL.SONO
INNER JOIN [manex].[dbo].[CUSTOMER] c ON c.CUSTNO = s.CUSTNO
INNER JOIN [manex].[dbo].[INVENTOR] i ON i.UNIQ_KEY = SODETAIL.UNIQ_KEY
INNER JOIN [manex].[dbo].[DUE_DTS] d ON d.SONO = s.SONO
INNER JOIN [manex].[dbo].[PLMAIN] p ON p.SONO = s.SONO
INNER JOIN [manex].[dbo].[PLDETAIL] q ON q.PACKLISTNO = p.PACKLISTNO
WHERE s.SONO LIKE '%12312'
SELECT * FROM #t
Here is a screenshot of the results from running this query:
Query Result
Now is when it should be time to join my due dates table (adding in the appropriate column(s) to my table definition and select statement) and make DATEDIFF comparisons to determine if shipments were on time or late. However, once I reference the due dates table, each of the 5 shipments is compared to all 5 dates in the due dates table, resulting in 25 rows. The only linking column DUE_DTS has is the SONO column. I've tried using DISTINCT and variations of the group by clause without success.
I've put enough together myself to figure joining the DUE_DTS table on SONO must be causing this to happen, as there are 5 instances of that value in the table (making it not unique) and a join should be based on a unique column. Is there a workaround for something like this?
You will need to use additional fields to join the records and reduce the results. You may need to link SONO to SODETAIL to DUE_DTS because the dates are tied to the items, not to the SONO.

How do I use the . properly with sql?

I am new to sql and have a question about joining 2 tables. Why is there a . in between customers.custnum in this example. What is its significance and what does it do?
Ex.
Select
customers.custnum, state, qty
From
customers
Inner join
sales On customers.custnum = sales.custnum
The . is to specify a column of a table.
Let's use your customer table; we could do:
SELECT c.custnum, c.state, c.qty FROM customers as c INNER JOIN
sales as s ON c.custnum = s.custnum
You don't really need the . unless two tables have columns with the same name.
In the below query, there are two tables being referred. One is CUSTOMERS another is STATE. Since both has same column CUSTNUM, we need a way to tell the database which CUSTNUM are we referring to. Same as there may be many Bob's, if so their last name is used for disambiguation.
I would consider the below style as more clearer. That's opinionated.
Select
cust.custnum, cust.state, s.qty
From
customers cust -- use alias for meaningful referencing, you may be self-joining, during that time you can use cust1, cust2 as aliases.
Inner join
sales as s On cust.custnum = s.custnum
Think of it as a way to categorize the hierarchical nature of the database. Within a DB, there are tables, and within tables there are columns. It's just a way of keeping track, especially if you are working with multiple tables that may have the same column name.
For example, a table called Sales and a table called Customers might both have a column called Date. You may be writing a query where you only want the date from the Sales table, so you would specify that by writing:
Select *
From Sales
inner join Customers on Sales.ID = Customers.ID
where Sales.Date = '1/1/2019'

Multiple table join query, with count in Oracle SQL

I'm trying to count the number of inspections of each property in YR_Inspection table by counting the number of times the property number occurs in the table, i then need to display this next to the town the city the property is located in and the branch the property belongs to all in the same query. Here is the link to my ERD to try and give this question some context,
http://www.gliffy.com/pubdoc/4239520/L.png
this is the code so far, it works so far but as soon as i add YR_Branch.CITY i get,
ORA-00979: not a GROUP BY expression
SELECT YR_Property.PROPERTYNUM, COUNT(YR_Inspection.PROPERTYNUM) AS Number_of_inspections
FROM YR_Property
INNER JOIN YR_Inspection
ON YR_Property.PROPERTYNUM = YR_Inspection.PROPERTYNUM
JOIN YR_Branch
ON YR_Property.BRANCHNUM = YR_Branch.BRANCHNUM
GROUP BY YR_Property.PROPERTYNUM
To add the branch number and the city for the branch, add max values for each to the query - like so:
SELECT YR_Property.PROPERTYNUM,
COUNT(YR_Inspection.PROPERTYNUM) AS Number_of_inspections,
MAX(YR_Branch.BRANCHNUM) AS Branch_Number,
MAX(YR_Branch.CITY) AS Branch_City
FROM YR_Property
INNER JOIN YR_Inspection
ON YR_Property.PROPERTYNUM = YR_Inspection.PROPERTYNUM
JOIN YR_Branch
ON YR_Property.BRANCHNUM = YR_Branch.BRANCHNUM
GROUP BY YR_Property.PROPERTYNUM

SQL like clause is not returning any results

I have following query, but it doesn't return any results for where clauses, even when there is row with that kind of name what is queried. If I remove where clause, then all records in Company table which have OfficeLocation table are returned. What is wrong in my query?
SELECT c.*
FROM [MyDb].[dbo].[Company] AS c
INNER JOIN [MyDb].[dbo].[CompanyOfficeLocation] AS col ON c.Id = col.CompanyId
INNER JOIN [MyDb].[dbo].[OfficeLocation] AS ol ON ol.Id = col.OfficeLocationId
WHERE ol.Name like '%Actual Name In This Table%';
Table structure :
Company
Id
etc ...
CompanyOfficeLocation
CompanyId
OfficeLocationId
OfficeLocation
Id
etc ...
Two things for a record to show up given your query:
The OfficeLocation you specified (given the ol.Name value) must have an Id value that is used by a record in the CompanyOfficeLocation table in its OfficeLocationId.
The CompanyOfficeLocation record that you got in #1 must have a CompanyId that exists in the Company table.
If any of those two criteria are not met, then no records will show up in your query result. The INNER JOIN is essentially an 'AND' clause. If a record could not be related to at least one INNER JOINed table, then that record will not show up at all.
If you want a record to show up despite not having any related records in the joined tables, you may want to consider using OUTER JOINs. A RIGHT JOIN in your case to be exact.
I do not find any mistake however I'd suggest you switch the columns after ON when joining to maintain standards.
Instead of - INNER JOIN [MyDb].[dbo].[OfficeLocation] AS ol ON ol.Id = col.OfficeLocationId
Do - INNER JOIN [MyDb].[dbo].[OfficeLocation] AS ol ON col.OfficeLocationId = ol.Id