A simple question about sqllite, stuck in the learning process - database

I'm trying to learn myself some sqlite. And i'm making some exercises.
I' m practicing in the sqlite practice area from W3 schools.
The question is to make the following query: Get the most expensive order(note. Some orders consist of more then one product(id))
I'm stuck in how I query for the sum of al the products related to the orderId.
Thanks in advance

I did it like this.
SELECT o.orderId,SUM(quantity*price) as totaal FROM [Orders] AS o
LEFT JOIN orderdetails AS ord ON O.orderId = ord.orderid
LEFT JOIN products AS P ON P.productid = ord.productId
GROUP BY O.orderId
ORDER BY Totaal DESC
LIMIT 1

Related

Inner join query completes but the results is wrong [duplicate]

This question already has answers here:
Two SQL LEFT JOINS produce incorrect result
(3 answers)
Closed 6 months ago.
When I run this:
SELECT
R.RegionID AS Region, C.CountryName AS Country,
S.SegmentName AS Segment, SUM(SKPI.KPI) AS YearlySalesKPI,
ROUND(SUM(SOLI.SalePrice), 2) AS YearlySales
FROM
Country C
INNER JOIN
Region R ON C.CountryID = R.CountryID
INNER JOIN
Segment S ON R.SegmentID = S.SegmentID
INNER JOIN
SalesRegion SR ON R.RegionID = SR.RegionID
INNER JOIN
SalesPerson SP ON SR.SalesPersonID = SP.SalesPersonID
INNER JOIN
SalesKPI SKPI ON SP.SalesPersonID = SKPI.SalesPersonID
INNER JOIN
SalesOrder SO ON SR.SalesRegionID = SO.SalesRegionID
INNER JOIN
SalesOrderLineItem SOLI ON SO.SalesOrderID = SOLI.SalesOrderID
INNER JOIN
Product P ON SOLI.ProductID = P.ProductID
INNER JOIN
ProductCost PC ON PC.ProductID = P.ProductID
AND PC.CountryId = C.CountryID
GROUP BY
R.RegionID, C.CountryName, S.SegmentName
ORDER BY
C.CountryName ASC, R.RegionID ASC;
The query takes over 1 minute to complete, and when it does it gives me results that are larger than the real values.
I believe the additional tables are adding additional rows - when it shouldn't. But I am unsure on how to stop this from happening. I think their might be something wrong with the relationships but I'm unsure.
I have tried all methods. Any help is appreciated.
This is my database:
Click here for the diagram
Results
Expected Result:
Expected results
Expected Results:
Expected results
The expected results are the above columns shown in one query output.
I'm not sure if I understand your problem.
Here are my thoughts:
For faster run time
Consider creating index for your tables.
Results that are larger than real values
If you are referring to YearlySalesKPI and YearlySales, duplicate rows might be the reason behind it, try running your query without sum first, check if there are repeating values, additional column joins will probably solve it.

How to join a table and aggregate the data by a different field than the key

I try to join a few tables in Dynamics AX and get all information per A.PARTYID on 1 row. However I have to join the other tables in a more detailed relationship.
Currently I try to join the following tables this way:
SELECT
A.PARTYID
,C.EMAIL
,C.PHONE
,C.RECID
FROM DIRPARTYTABLE A
LEFT JOIN DIRPARTYECOMMUNICATIONRELA2608 B
ON B.PARTYID = A.PARTYID
LEFT JOIN DIRECOMMUNICATIONADDRESS C
ON C.RECID = B.RECID
WHERE
B.PARTYID = 00000225
And this is the result:
PARTYID MAIL PHONE RECID
000000225 asdf#gmail.com NULL 5637146657
000000225 NULL 0612345678 5637176698
However I want to aggregate the information by PARTYID and leave out the RECID, since I'm not interested in that, like this:
PARTYID MAIL PHONE
000000225 asdf#gmail.com 0612345678
Does anyone have a suggestion how I can adjust the code to make it work?
Sorry the question may seem vague, since I don't entirely know what keywords to use to describe this.
Kind regards,
Igor
Can't you just
SELECT
A.PARTYID
,MAX(C.EMAIL) Email
,MAX(C.PHONE) Phone
FROM DIRPARTYTABLE A
LEFT JOIN DIRPARTYECOMMUNICATIONRELA2608 B
ON B.PARTYID = A.PARTYID
LEFT JOIN DIRECOMMUNICATIONADDRESS C
ON C.RECID = B.RECID
WHERE
B.PARTYID = '00000225' --00000225 is a string not a number
GROUP BY A.PARTYID;
This should work
SELECT SQ1.PARTYID,
MAX(SQ1.MAIL) AS Mail,
MAX(SQ1.PHONE) AS Phone
FROM (
VALUES ('000000225','asdf#gmail.com',NULL,5637146657),
('000000225',NULL,'0612345678',5637176698)
) AS SQ1(PARTYID,MAIL,PHONE,RECID)
GROUP BY SQ1.PARTYID;

SQL Query Multiple Joins Unexpected Results

My task is to write a query that will return sales information for each customer category and year. The columns required in the result set are:
OrderYear - the year the orders were placed
CustomerCategoryName - as it appears in the table Sales.CustomerCategories
CustomerCount - the number of unique customers placing orders for each CustomerCategoryName and OrderYear
OrderCount - the number of orders placed for each CustomerCategoryName and OrderYear
Sales - the subtotal from the orders placed, calculated from Quantity and UnitPrice of the table Sales.OrderLines
AverageSalesPerCustomer - the average sales per customer for each CustomerCategoryName and OrderYear
The results should be sorted in ascending order, first by order year, then by customer category name.
My attempt at a solution:
SELECT
CC.CustomerCategoryName,
YEAR(O.OrderDate) AS OrderYear,
COUNT(DISTINCT C.CustomerID) AS CustomerCount,
COUNT(DISTINCT O.OrderID) AS OrderCount,
SUM(OL.Quantity * OL.UnitPrice) AS Sales,
SUM(OL.Quantity * OL.UnitPrice) / COUNT(DISTINCT C.CustomerID) AS AverageSalesPerCustomer
FROM
Sales.CustomerCategories CC
INNER JOIN
Sales.Customers C ON C.CustomerCategoryID = CC.CustomerCategoryID
INNER JOIN
Sales.Orders O ON O.CustomerID = C.CustomerID
INNER JOIN
Sales.OrderLines OL ON OL.OrderID = O.OrderID
GROUP BY
CC.CustomerCategoryName, YEAR(O.OrderDate)
ORDER BY
YEAR(O.OrderDate), CC.CustomerCategoryName;
My OrderCount seems correct. However, I don't believe my CustomerCount is correct and my Sales and AverageSalesPerCustomer seem way off. The Categories that do not have any customers and orders do not show up in my results.
Is the reason that my counts are off and that he categories that do not have any customers are omitted is because they only have null values? I believe the question is looking for all the categories.
I am using the sample tables of WideWorldImporters from Microsoft.
Any help would be appreciated as I am new to SQL and Joins are a very hard concept for me to understand.
Presently, you're getting only the data that exists in order details...and not getting anything for the non-existent orders. Normally, this is accomplished with outer joins instead of inner joins, and an isnull(possiblyNullValue,replacementValue).
Also, while you're grouping by year(o.OrderDate), your join for orders isn't distinguishing by year...probably getting all years worth of data for each customer for each reporting period.
So, let's get the reporting period out first...and make sure we're basing our results on that:
select distinct year(o.OrderDate) from Sales.Orders
But really, you want all categories and all years...so you can combine them to get the real basis:
select
cc.CustomerCategoryId,
cc.CustomerCategoryName,
year(o.OrderDate)
from
Sales.Orders o
cross join
Sales.CustomerCategories cc
group by
cc.CustomerCategoryId,
cc.CustomerCategoryName,
year(o.OrderDate)
Now, you want to join this mess into the remaining query. There are two ways to do this...one is to use a with clause...but sometimes it's just easier to just wrap the basis query up in parentheses and use it as if it was a table:
select
cy.CustomerCategoryName,
cy.CalendarYear,
count(distinct c.CustomerId) CustomerCount,
isnull(sum(ol.UnitPrice * ol.Quantitiy),0.0) Sales,
isnull(sum(ol.UnitPrice * ol.Quantitiy) / count(distinct c.CustomerId),0.0) AverageSalesPerCustomer
from
(
select
cc.CustomerCategoryId,
cc.CustomerCategoryName,
year(o.OrderDate) CalendarYear --> must name calc'd cols in virtual tables
from
Sales.Orders o
cross join
Sales.CustomerCategories cc
group by
cc.CustomerCategoryId,
cc.CustomerCategoryName,
year(o.OrderDate)
) as cy --> cy is the "Category Years" virtual table
left outer join
Sales.Customers c
on cy.CustomerCategoryId = c.CustomerCategoryId
left outer join
Sales.Orders o
on
c.CustomerId = o.CustomerId --> join on customer and year
and --> to make sure we're only getting
cy.CalendarYear = Year(o.OrderDate) --> orders in the right year
left outer join
Sales.OrderLines ol
on o.OrderId = ol.OrderId
group by
cy.CalendarYear,
cy.CustomerCategoryName
order by
cy.CalendarYear,
cy.CustomerCategoryName
By the way...get comfortable messing with your queries to select some subset...for example, you can add a where clause to select only one company...and then go have a look at the details...to see if it passes the smell test. It's a lot easier to evaluate the results when you limit them. Similarly, you can add the customer to the select list and the outer grouping for the same reason. Experimentation is the key.

Display only Companies that does not supply "Beverages" in Microsoft SQL

having trouble here with SQL statement for displaying companies that does not supply beverages. Now the problem here is that there are few companies that supply both beverage and other stuff. I need it to only display companies that does not supply beverages at all. When i run my modified SQL statement, i managed to get what i want but, for those companies that supply foods as well as beverages, it is still being displayed because of my WHERE clause i set to search for C.CategoryName != 'Beverages'. I just want to remove those companies that supply both beverages and foods so i can only display those companies that purely supply only foods.
Sorry if i have some grammer mistake or anything or my question is unclear. I just don't really know how to explain professionally as it is hard to describe my problem. Thanks for those who willing to help me, i am really appreciate it. And also i do not know if these info and source codes are sufficient regarding my problem. Will provide more info/source code if needed.
Pictures of Both Category & Products table.
Category Table
Products Table
Here's the Initial statement
SELECT P.ProductName
FROM Products AS P
INNER JOIN
Categories AS C
ON
C.CategoryID = P.CategoryID
AND C.CategoryName = 'Beverages'
Result
So far here's the modified statement
SELECT S.CompanyName, P.CategoryID, C.CategoryID FROM Suppliers AS S
INNER JOIN
Products AS P
ON S.SupplierID = P.SupplierID
LEFT OUTER JOIN
Categories AS C
ON
C.CategoryID = P.CategoryID
AND C.CategoryName != 'Beverages'
Result
Answer Suggested by Martin Smith.
With adding EXCEPT Clause to the SQL statement to my modified SQL statement, i managed to get it done. Here is the Answer to my problem.
SELECT S.CompanyName FROM Suppliers AS S
EXCEPT
SELECT S.CompanyName FROM Suppliers AS S
INNER JOIN
Products AS P
ON S.SupplierID = P.SupplierID
RIGHT JOIN
Categories AS C
ON
C.CategoryID = P.CategoryID
AND C.CategoryName = 'Beverages'
WITH FOODSUPPLIERS AS
(
SELECT DISTINCT SUPPLIERID
FROM PRODUCTS P
JOIN CATEGORY C ON C.CATEGORYID = P.CATEGORYID
WHERE CATEGORYNAME <> 'Beverages'
)
SELECT S.COMPANYNAME FROM SUPPLIERS S
JOIN FOODSUPPLIERS FS ON FS.SUPPLIERID = S.SUPPLIERID
The FOODSUPPLIERS CTE identifies suppliers in PRODUCTS that are not associated with any beverage products, i.e., associated only with food products. It's then a simple matter of joining the CTE to Suppliers to get the records for these suppliers.

SQL Server: Show a list of Customers that have more Orders than a specify Customer

Yop guys, I have this little question to solve; I have 2 tables [Customers] and [Orders] who are linked by CustomerID. It's easy to get the COUNT() of Orders by each Customers...
SELECT c.CompanyName, COUNT(*) AS [Nbr of Orders]
FROM [Orders] o
INNER JOIN [Customers] c
ON c.CustomerID = o.CustomerID
GROUP BY c.CompanyName
But the problem come from the last part of the question: I need to get that list but only those that have more Orders than one of those Customers (c.CompagnyName = 'XYZ')
I tried to add something like this WHERE clause
WHERE COUNT(*) > (SELECT COUNT(*)
FROM [Orders] o
INNER JOIN [Customers] c
ON c.CustomerID = o.CustomerID
WHERE c.CompagnyName = 'XYZ')
SQL Error :P
Look like ridiculous I know but if someone can tell me what I miss on !
Looks like you can use a having clause. So your example would be
SELECT c.CompanyName, COUNT(*) AS [Nbr of Orders]
FROM [Orders] o
INNER JOIN [Customers] c
ON c.CustomerID = o.CustomerID
GROUP BY c.CompanyName
having count(*) > 1
I think you want a HAVING clause rather than a WHERE clause, as you are filtering on an aggregated function

Resources