Related
I have a question for an assignment with 5 tables as shown below. I need to write a query with the minimum cost for each sport:
2nd column is equipment_name:
I think I need to do a bunch of joins in subqueries with the primary keys being the id columns and the foreign keys the name_id columns. Is this the right approach?
You don't need a bunch of joins; minimally this question can be solved by one join between the store_equipment_price and the sports_equipment tables - if these two are joined on equipment id then you'll effectively get rows that can give the cost of starting up in each sport per store. You'll need to group by the sport id and the store id; don't forget that it might be cheaper to start soccer by getting all the gear from store A but it might be cheaper to start golf by going to tore B - tho I how I read the question. If however you're prepared to get your gloves from store A and your bat from store B etc then we don't even group by the store when summing, instead we work out which store is cheapest for each component rather than which store is cheapest for each sport overall.
If you're after producing named stores/sports on your result rows then you'll need more joins but try getting the results right based on the fewest number of joins possible to start with
Both these queries will ultimately be made a lot easier by the use of an analytic/windowing function but these are database dependent; never post an sql question up without stating what your db vendor is, as there are few questions that are pure ISO SQL
You question is not completely clear, I assume you need to find stores from which to buy each equipment for all sports so as to incur minimum expense. Following query will achieve this
select s.sports, e.equipment_name, min(sep.price),
(select store_name from stores st where st.id = sep.store_id) store_name
from sports s
join sports_equipment se on s.id = se.sport_id
join equipment e on e.id = se.equipment_id
join sports_equipment_prices sep on sep.equipment_id = se.equipment_id
group by s.sports, e.equipment_name
order by s.sports, e.equipment_name
;
Following 'create table' and 'insert data' script are based on your screen images
create table sports (
id INTEGER PRIMARY KEY AUTOINCREMENT,
sports varchar(50)
);
insert into sports(sports) values('golf');
insert into sports(sports) values('baseball');
insert into sports(sports) values('soccer');
create table stores (
id INTEGER PRIMARY KEY AUTOINCREMENT,
store_name varchar(50)
);
insert into stores(store_name) values('A');
insert into stores(store_name) values('B');
insert into stores(store_name) values('C');
create table equipment (
id INTEGER PRIMARY KEY AUTOINCREMENT,
equipment_name varchar(50)
);
insert into equipment(equipment_name) values('shoes');
insert into equipment(equipment_name) values('ball');
insert into equipment(equipment_name) values('clubs');
insert into equipment(equipment_name) values('glove');
insert into equipment(equipment_name) values('bat');
create table sports_equipment (
sport_id INTEGER not null,
equipment_id INTEGER not null,
FOREIGN KEY(sport_id) REFERENCES sports(id),
FOREIGN KEY(equipment_id) REFERENCES equipment(id)
);
insert into sports_equipment values(1, 1);
insert into sports_equipment values(1, 2);
insert into sports_equipment values(1, 3);
insert into sports_equipment values(2, 2);
insert into sports_equipment values(2, 4);
insert into sports_equipment values(2, 5);
insert into sports_equipment values(3, 1);
insert into sports_equipment values(3, 2);
create table sports_equipment_prices (
id INTEGER PRIMARY KEY AUTOINCREMENT,
store_id INTEGER not null,
equipment_id INTEGER not null,
price INTEGER not null,
FOREIGN KEY(store_id) REFERENCES stores(id),
FOREIGN KEY(equipment_id) REFERENCES equipment(id)
);
I have three table
emp(id, name)
product(id, productname)
sales(id,emp_id,product_id,saleprice)
List all the employee with total sales.
Fetch the employee with highest sales.
Note: I dont want to use joining and subquery, please suggest me better way.
If you could refer to emp_id only then there is no need to use JOIN at all:
SELECT emp_id, SUM(salesprice) AS total_sales
FROM sales
GROUP BY emp_id
ORDER BY total_sales DESC -- comment 2 lines to get answer for 1 question
LIMIT 1; -- MySQL version for SQL Server use `SELECT TOP 1`
Please note that if specific employee does not have any sales then it will be skipped. You won't get 0/NULL value for non existing data.
EDIT:
If you decide to use JOIN then:
SELECT e.id, e.name, SUM(s.salesprice) AS total_sales
FROM emp e
LEFT JOIN sales s
ON e.id = s.emp_id
GROUP BY e.id, e.name
ORDER BY BY total_sales DESC LIMIT 1;
I think you can do like this. But better way is use join statement.But as your requirement you can do like this. I think this is this easiest way and very simple query.
I have provided create table and sample data insert query.
This is answer for your requirement
-- 1.List all the employee with total sales.
select distinct E.Id,E.Name,P.Productname,S.saleprice from Sales S,Emp E,Product P
where E.Id=S.Emp_id and P.Id=S.Product_id
See result for 1st question here
-- 2.Fetch the employee with highest sales.
select S.Emp_id,E.Name,SUM(S.saleprice) AS TotalSalePrice from Sales S,Emp E
where E.Id=S.Emp_id
Group By S.Emp_id,E.Name
See result for 2nd question here
This is create table and sample data insert querys which create for your requirement
create table Emp
(
[Id] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,
[Name] [nvarchar](100)
);
create table Product(
[Id] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,
[Productname] [nvarchar](100)
);
create table Sales(
[Id] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,
[Emp_id] [int] FOREIGN KEY REFERENCES Emp([Id]) ,
[Product_id] [int] FOREIGN KEY REFERENCES Product([Id]) ,
[saleprice] [int] NOT NULL
);
INSERT INTO [dbo].[Emp] ([Name]) VALUES('Jone Doe')
INSERT INTO [dbo].[Emp] ([Name]) VALUES('Micheal Oshea')
INSERT INTO [dbo].[Emp] ([Name]) VALUES('Ish Thalagala')
INSERT INTO [dbo].[Emp] ([Name]) VALUES('Mark Poull')
INSERT INTO [dbo].[Emp] ([Name]) VALUES('Janne Marker')
INSERT INTO [dbo].[Product]([Productname]) VALUES ('Coca Cola')
INSERT INTO [dbo].[Product]([Productname]) VALUES ('Pepsi')
INSERT INTO [dbo].[Product]([Productname]) VALUES ('Tooth Brush')
INSERT INTO [dbo].[Product]([Productname]) VALUES ('Water Filter')
INSERT INTO [dbo].[Product]([Productname]) VALUES ('Playstation 4 pro')
INSERT INTO [dbo].[Sales]([Emp_id],[Product_id],[saleprice])VALUES(1,1,10)
INSERT INTO [dbo].[Sales]([Emp_id],[Product_id],[saleprice])VALUES(1,4,500)
INSERT INTO [dbo].[Sales]([Emp_id],[Product_id],[saleprice])VALUES(2,2,10)
INSERT INTO [dbo].[Sales]([Emp_id],[Product_id],[saleprice])VALUES(2,5,600)
INSERT INTO [dbo].[Sales]([Emp_id],[Product_id],[saleprice])VALUES(2,4,500)
INSERT INTO [dbo].[Sales]([Emp_id],[Product_id],[saleprice])VALUES(3,1,10)
INSERT INTO [dbo].[Sales]([Emp_id],[Product_id],[saleprice])VALUES(3,2,10)
INSERT INTO [dbo].[Sales]([Emp_id],[Product_id],[saleprice])VALUES(3,3,30)
INSERT INTO [dbo].[Sales]([Emp_id],[Product_id],[saleprice])VALUES(3,4,500)
INSERT INTO [dbo].[Sales]([Emp_id],[Product_id],[saleprice])VALUES(3,5,600)
INSERT INTO [dbo].[Sales]([Emp_id],[Product_id],[saleprice])VALUES(4,1,10)
INSERT INTO [dbo].[Sales]([Emp_id],[Product_id],[saleprice])VALUES(5,4,500)
INSERT INTO [dbo].[Sales]([Emp_id],[Product_id],[saleprice])VALUES(5,5,600)
I am trying to populate an attendance system with values from a legacy system.
I am currently tracking all_time attendance (which is simple), attendance in this year, and attendance since last grading (examination). To avoid potential contamination, I am storing legacy data, and want to import it into my totals a bit at a time.
This is my basic data model:
-- information about the attendee
CREATE TABLE core_member (
id INT UNSIGNED AUTO_INCREMENT,
name VARCHAR (250),
dob DATE,
last_grade_date date default '2014-12-14',
grade INT UNSIGNED NOT NULL DEFAULT 50,
PRIMARY KEY (id)
);
-- attendee data
INSERT INTO core_member values(1, 'Donald Duck', '1950-03-01', '2015-06-15', 10);
INSERT INTO core_member values(2, 'Goofy', '1950-04-17', '2014-06-15', 42);
-- attendance sums (1:1 with antendee)
CREATE TABLE core_attendance(
medlemsid INT UNSIGNED,
imported INT DEFAULT 0,
all_time INT DEFAULT 0,
since_last_grad INT DEFAULT 0,
UNIQUE KEY medlemsid (medlemsid),
FOREIGN KEY (medlemsid) REFERENCES core_member (id)
);
-- attendance sum data
INSERT INTO core_attendance values(1,100,150,0);
INSERT INTO core_attendance values(2,80,103,3);
-- historic attendance
CREATE TABLE core_historic_attendance (
medlemsid int(10) unsigned NOT NULL,
year int(11) NOT NULL,
month enum('none','januar','februar','marts','april','maj','juni','juli','august','september','oktober','november','december') NOT NULL DEFAULT 'none',
attendance int(11) DEFAULT '0',
UNIQUE KEY unq (medlemsid,year,month),
KEY medlemsid_idx (medlemsid),
CONSTRAINT medlemsid FOREIGN KEY (medlemsid) REFERENCES core_member (id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
-- historic attendance data
INSERT INTO core_historic_attendance values(1,2011,'none',54);
INSERT INTO core_historic_attendance values(1,2012,'none',43);
INSERT INTO core_historic_attendance values(1,2013,'none',61);
INSERT INTO core_historic_attendance values(1,2014,'none',49);
INSERT INTO core_historic_attendance values(1,2015,'januar',19);
INSERT INTO core_historic_attendance values(1,2015,'februar',14);
INSERT INTO core_historic_attendance values(1,2015,'marts',17);
INSERT INTO core_historic_attendance values(2,2011,'none',54);
INSERT INTO core_historic_attendance values(2,2012,'none',43);
INSERT INTO core_historic_attendance values(2,2013,'none',61);
INSERT INTO core_historic_attendance values(2,2014,'none',49);
INSERT INTO core_historic_attendance values(2,2015,'januar',19);
INSERT INTO core_historic_attendance values(2,2015,'februar',4);
INSERT INTO core_historic_attendance values(2,2015,'marts',7);
I need to add the sum of all the values from core_historic attendance where the year is greater than the year of the last grading to the since_last_grad column in the core_member table, for the member in question (initial load).
I gather from this post ( mysql update column with value from another table ), that I have to do something like
UPDATE core_members INNER JOIN core_historic_attendance ON id = core_historic_attendance.medlemsid having`year` > year(last_grad_date)
SET since_last_grad = since_last_grad + SUM(attendance);
But I'm a bit stuck, since i want only the sum of the core_historic_attendance records where the year is greater than year(last_grad_date)
EDIT:
I have corrected the SQL as suggested by Sasha, nut I get an error code 1111 "Invalid use of group function"
I have created an SQL Fiddle as well
Does this work for you:
CREATE TEMPORARY TABLE t1 (key(medlemsid)) SELECT core_historic_attendance.medlemsid,SUM(attendance) as total_attendance
FROM core_member INNER JOIN core_historic_attendance ON
id = core_historic_attendance.medlemsid AND `year` > year(last_grade_date)
GROUP BY medlemsid;
UPDATE core_attendance INNER JOIN t1 USING(medlemsid)
SET since_last_grad = since_last_grad + t1.total_attendance;
?
I need to know that how to fetch a record from table which consist of certain records varies with different id named[sponser_id]
from the above img i give you a simple scenario..say for ex: the rounded person is said to be the person A.
when Person A loggin into his/her acc. It should show how many members(count) are coming under his/her control.
Mysql table has columns like
sponser_id refers to the parent user_id.
sponser_id varies with parent_user who referred them.
Here my question is, How to retrieve the count of members under this particular person..
I have only user_id & sponser_id columns alone in my table.
Here is an MLM tree I once implemented here, I think I deleted the answer cuz it was not appreciated :)
I always do these with Stored Procedures. A member can have a parent, like your setup.
The output showed downline sales and a commission at 5%
Schema
-- drop table member;
create table member
( memberId int not null auto_increment primary key,
handle varchar(255) not null,
parentId int null,
key (parentId)
);
-- drop table sales
create table sales
( -- sales of Products abbreviated
id int auto_increment primary key,
memberId int not null,
amount decimal(10,2) not null,
saleDate datetime not null,
CONSTRAINT `fk_member`
FOREIGN KEY (memberId)
REFERENCES member(memberId)
);
insert member(handle,parentId) values ('Johnny Two-Thumbs',null); -- 1
insert member(handle,parentId) values ('Jake the Enforcer',null); -- 2
insert member(handle,parentId) values ('Innocent Kim',2); -- 3
insert member(handle,parentId) values ('Karen',2); -- 4
insert member(handle,parentId) values ('Henry',2); -- 5
insert member(handle,parentId) values ('Shy Sales-less Sam',5); -- 6
insert member(handle,parentId) values ('Pete',5); -- 7
insert member(handle,parentId) values ('Iowa Mom',7); -- 8
insert member(handle,parentId) values ('Albuquerque Agoraphobiac',7); -- 9
insert sales (memberId,amount,saleDate) values (2,1,'2015-01-01');
insert sales (memberId,amount,saleDate) values (5,10,'2015-01-20');
insert sales (memberId,amount,saleDate) values (5,15.50,'2015-01-22');
insert sales (memberId,amount,saleDate) values (7,101.12,'2015-02-01');
insert sales (memberId,amount,saleDate) values (7,201.12,'2015-03-01');
insert sales (memberId,amount,saleDate) values (7,109,'2015-04-01');
insert sales (memberId,amount,saleDate) values (7,45,'2015-05-01');
insert sales (memberId,amount,saleDate) values (8,111,'2015-04-20');
insert sales (memberId,amount,saleDate) values (8,99.99,'2015-05-22');
insert sales (memberId,amount,saleDate) values (9,0.04,'2015-06-20');
insert sales (memberId,amount,saleDate) values (9,1.23,'2015-06-24');
Stored Procedure
drop procedure if exists showAllDownlineSales;
DELIMITER $$
create procedure showAllDownlineSales
(
theId int
)
BEGIN
-- theId parameter means i am anywhere in hierarchy of membership
-- and i want all downline sales
-- return 1 row: sales amt for downlines, and that amt * 5%, and total children (including children-of-children)
declare bDoneYet boolean default false;
declare working_on int;
declare theCount int;
declare downlineSales decimal(10,2);
declare commish decimal(10,2);
CREATE temporary TABLE xxFindSalesxx
(
memberId int not null,
processed int not null, -- 0 for not processed, 1 for processed
salesTotal decimal(10,2) not null
);
set bDoneYet=false;
insert into xxFindSalesxx (memberId,processed,salesTotal) select theId,0,0;
while (!bDoneYet) do
select count(*) into theCount from xxFindSalesxx where processed=0;
if (theCount=0) then
-- found em all
set bDoneYet=true;
else
-- one not processed yet, insert its children for processing
SELECT memberId INTO working_on FROM xxFindSalesxx where processed=0 limit 1;
insert into xxFindSalesxx (memberId,processed,salesTotal)
select memberId,0,0 from member
where parentId=working_on;
-- update xxFindSalesxx
-- join sales
-- on sales.memberId=xxFindSalesxx.memberId
-- set salesTotal=sum(sales.amount)
-- where xxFindSalesxx.memberId=working_on;
update xxFindSalesxx
set salesTotal=(select ifnull(sum(sales.amount),0) from sales where memberId=working_on)
where xxFindSalesxx.memberId=working_on;
-- mark the one we "processed for children" as processed
update xxFindSalesxx set processed=1 where memberId=working_on;
end if;
end while;
delete from xxFindSalesxx where memberId=theId;
select sum(salesTotal),count(*) into downlineSales,theCount from xxFindSalesxx;
drop table xxFindSalesxx;
select downlineSales,round(downlineSales*0.05,2) as commission,theCount; -- there is your answer, 1 row
END
$$
DELIMITER ;
Test it
call showAllDownlineSales(2); -- 693.00 34.69 7
call showAllDownlineSales(1); -- null null 0
call showAllDownlineSales(5); -- 668.50 33.43 4
MY situation is like this:
I have two tables
TEACHERS and ABSENCES each of them has a column unitid
I want to select the unitid from TEACHERS Table and insert into ABSENCES table.
EDIT:
Can this be added into this query: ("insert into absences (student_id, date) values ('".$_GET['student_id']."','".date('Y-m-d H:i:s')."')");
?
try this
INSERT INTO ABSENCES(unitid) select unitid from TEACHERS
I tried to depict your scenario as below
Create Absence Table
create table absence (absence_id int not null auto_increment primary key,
`date` datetime, `subject` varchar(20),
unit_session varchar(20), unitid int);
Insert Data to Absence Table
insert into absence(`date`, `subject`, unit_session)
values(now(),'Math','first'),(now(),'Biology','second'),(now(),'Physics','third')
Create and insert data to Teachers table
create table teachers (username varchar(10), `password` varchar(10), unitid int);
insert into teachers values('abcdsed','fgdfgfdfgd',23),
('abcdced','fgdfgrtfgd',3),('harikas','fgdfgfdfgd',23);
At this point as you can see, Absence Table don't have any value for unitid column. it's NULL.
Create a temporary table as below
create temporary table temptest(id int not null auto_increment primary key,
unit_id int);
Insert unitid from Teachers to temporary table
insert into temptest(unit_id) select unitid from teachers
Now finally, update Absence table by joining with temporary table like below
UPDATE absence a
JOIN temptest b
ON a.absence_id = b.id
SET a.unitid = b.unit_id