Group and Ordering in SQL - sql

I need to make a query in SQL that can display the top selling book. for this I need to do a inner join and I get a problem after I did the inner join. Here is my code:
CREATE VIEW mostpopularbookssold AS
SELECT Count(orders.book_id) AS numberofbookssold ,
Top(1) books.[Name]
FROM orders
INNER JOIN books
ON books.id=orders.book_id
GROUP BY books.[Name]
select *
FROM mostpopularbookssold

The TOP(1) should be placed at the start of your query, after SELECT. Furthermore you have to make an ordering by the books sold:
CREATE VIEW MostPopularBooksSold
AS
SELECT TOP(1)
COUNT(Orders.Book_ID) AS NumberOfBooksSold
, Books.[Name]
FROM [the database name].[schema name].[Orders] AS Orders
INNER JOIN [the database name].[schema name].[Books] AS Books
ON Books.ID = Orders.Book_ID
GROUP BY Books.[Name]
ORDER BY COUNT(Orders.Book_ID) DESC
You should replace the database name with the name of the database, in which you have created the corresponding tables and you have replace the schema name with the schema name, under which you have created the corresponding tables (usually this is the dbo, if you haven't stated explicitly a schema name).

Related

sql - does join create a new table?

when I use join in mysql (or sql) does it create a new table?
Or does it create a virtual table like the view command?
NO, it doesn't create the new table within the database but it only shows the output of the table. Yeah, it is just a kind of output
For example I have two tables
my join query:
--Alias inner join
select t1.Table2_id, t1.[Name], t1.Class,
t1.Age, t2.Fee, t2.No_of_courses from Table_1 as t1
inner join Table_2 as t2 on
t1.Table2_id=t2.id
enter image description here
So it's just the temporary to show us the result of the join.
Each query result is a table. It consists of columns and rows and can be treated like any other table in SQL. E.g.:
select *
from departments
join
(
select department_id, count(*) as number_of_employees
from employees
group by department_id
) department_info using (department_id);
Here we create a table we call department_info in our query and join this table to the existing departments table. This creates another table now consisting of departments plus the number of employees in it. This is the query result we show.
It is a query (select ...) which creates a table. The join is just a part of it.
These tables, however, are only temporary. While departments and employees in above example are stored tables, department_info and the final query result are not. They don't get stored. If you want to store a query's result table, use CREATE TABLE AS. E.g.:
create table department_employees as
select *
from departments
join
(
select department_id, count(*) as number_of_employees
from employees
group by department_id
) department_info using (department_id);

SQL statement to retrieve data from single table by comparing with multiple table entries

I have a table category, profile and employee_belongs_to, where employee_belongs_to stores profile_id and category_id. The profile table stores all the employees details. category table stores different category like English, math,physics ...
I want to select only name from profile table to which profile_id corresponds to particular category_id in employee_belongs_to table.
How can i write the SQL statement?
You can join the tables and write query like shown below
SELECT *
FROM profile INNER JOIN employee_belongs_to ON employee_belongs_to.profileID = profile.ProfileID
INNER JOIN category ON category.categoryID = employee_belongs_to.categoryID
WHERE category.categoryID = #CategoryID
The following SQL statement worked for me:
SELECT profile.* FROM profile JOIN employee_belongs_to JOIN category ON employee_belongs_to.Profile_id=profile.Profile_id AND employee_belongs_to.Category_id=category.Category_id WHERE category.Category_id=?

Trouble understanding an SQL query for a many-to-many table

I have a many-to-many table which manages stock between stores and products
I'm trying to create a simple query to show all the rows in store_stock but in a more user friendly way by showing the product name and store name.
I've tried a few variations of this but I just keep getting errors
SELECT product.product_name, store.store_name, store_stock.quantity
FROM store_stock
INNER JOIN product ON store_stock.product_id = product.product.id
INNER JOIN store ON store_stock.store_id = store.store_id
When I do it via phpMyAdmin query tab it runs this: (However I had to change it from LEFT JOINs to INNER JOINs)
SELECT `product`.`name` AS `product_name`, `store`.`name` AS `store_name`, `store_stock`.`quantity`
FROM `product`
INNER JOIN `store_stock` ON `store_stock`.`product_id` = `product`.`product_id`
INNER JOIN `store` ON `store_stock`.`store_id` = `store`.`store_id`
ORDER BY `product`.`name` ASC, `store`.`name` ASC
This works, but what I don't understand is why it runs 'FROM product', instead of 'FROM store_stock' table

SQL Query to find MAX Date

I have some software that uses dBase4 for its database. I am attempting to construct a report using fields from 3 tables (Customer, Service & History).
In all of the tables the ACCOUNT field is the same. The 'Customer' and the 'Service' table only have one one record for each Customer. The 'History' table has multiple records for each Customer.
I need to write a query so that only the record with the MAX date in 'History.BILLTHRU' is returned for each Customer. The code below returns all of the records for each Customer in the History table:
SELECT Customer.ACCOUNT,
Customer.FIRSTNAME,
(more fields...),
History.ACCOUNT,
History.BILLTHRU,
Service.ACCOUNT,
Service.OFFERCODE
FROM "C:\Customer.dbf" Customer
INNER JOIN "C:\History.dbf" History
ON (Customer.ACCOUNT = History.ACCOUNT)
INNER JOIN "C:\Service.dbf" Service
ON (Customer.ACCOUNT = Service.ACCOUNT)
WHERE Customer.STATUS = "A"
ORDER BY Customer.LAST_BUS_NAME
Use a sub-query and a group by:
SELECT Customer.ACCOUNT,
Customer.FIRSTNAME,
(more fields...),
History.ACCOUNT,
History.BILLTHRU,
Service.ACCOUNT,
Service.OFFERCODE
FROM "C:\Customer.dbf" Customer
INNER JOIN (SELECT ACCOUNT, MAX(BILLTHRU) AS BILLTHRU
FROM "C:\History.dbf"
GROUP BY ACCOUNT) History
ON (Customer.ACCOUNT = History.ACCOUNT)
INNER JOIN "C:\Service.dbf" Service
ON (Customer.ACCOUNT = Service.ACCOUNT)
WHERE Customer.STATUS = "A"
ORDER BY Customer.LAST_BUS_NAME
I like to use common table expressions (CTEs). Subqueries are good, but breaking it out like this sometimes makes it easier to keep separate.
with GetMaxDate as (
select account, max(billthru) as MaxBillThru
from "C:\History.dbf"
group by account
)
SELECT Customer.ACCOUNT,
Customer.FIRSTNAME,
(more fields...),
GetMaxDate.ACCOUNT,
GetMaxDate.MaxBillThru,
Service.ACCOUNT,
Service.OFFERCODE
.....
from FROM "C:\Customer.dbf" Customer
INNER JOIN GetMaxDate on customer.ACCOUNT = GetMaxDate.Account
INNER JOIN "C:\Service.dbf" Service
ON (Customer.ACCOUNT = Service.ACCOUNT)
WHERE Customer.STATUS = "A"
ORDER BY Customer.LAST_BUS_NAME
EDIT: This is a SQL Server function. I'm leaving it in case it can help you or someone else. I'll delete it if it just clouds the issue.

Join query from table with multiple foreign keys to same table primary key

I have a workorder system using SQL Express 2008. I have a table called Workorders that has several personnel that are linked to it via UserID. In the Workorder table I have TechID for the Technician, CustomerID for the Customer, QAID for quality assurance. These are linked back to the User Table via UserID (User Table PK). I want to join the tables to return Technician Name, Customer Name, and QA Name from the User Table and other job information information from the Workorder Table. I have no idea how to construct the join.
What about something a bit like this :
select tech.name as tech_name,
customer.name as customer_name,
qa.name as qa_name
from Workorders
inner join User as tech on tech.userId = Workorders.techId
inner join User as customer on customer.useId = Workorders.CustomerId
inner join User as qa on qa.useId = Workorders.QAID
(Might need some tunning, but the idea should be here)
ie, you are :
starting with a workorder
inner join on its tech guy (a User),
and then inner joinning on its customer (another user)
and so on
And this allows you to get each name, using the right alias in the select clause.
Note that I used aliases in the select clause too -- that might be usefull to have "worker_name" and "tech_name", instead of just two columns names "name" -- especially if you are calling this query from some other programming language.
Note : if one of those userId field can be NULL, you might want to use a left join, instead of an inner join.
select tus.Name as 'TechnicianName',
cus.Name as 'CustomerName',
qus.Name as 'QaName',
wod.*
from WorkOrders wod
left outer join
Users tus on tus.UserId = wod.TechId
left outer join
Users cus on cus.UserId = wod.CustomerId
left outer join
Users qus on qus.UserId = wod.QaId