Grouping Contiguous Rows in two Columns - sql-server-2008

I have a table in which there are two rows From_ID and To_ID. I need rows grouped on based of having same Work_ID and the grouping should start from From_ID and should take its To_ID and look for the row having From_ID as To_ID of that row. These cannot be in sequence. And the group should end only when there is no row having From_ID as To_ID. I think table definition and screenshot will clear my query.
CREATE TABLE [dbo].[tblttt](
[ID] [bigint] IDENTITY(1,1) NOT NULL,
[Work_ID] [nvarchar](max) NULL,
[From_ID] [int] NULL,
[To_ID] [int] NULL,
[Share] [float] NULL,
CONSTRAINT [PK_tblttt] PRIMARY KEY CLUSTERED
(
[ID] ASC
))
GO
SET IDENTITY_INSERT [dbo].[tblttt] ON
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (1, N'051111Clus', 30500004, 30500005, 0.025)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (2, N'051111Clus', 30500004, 30500007, 0.025)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (3, N'051111Clus', 30500004, 30500009, 0.25)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (4, N'051111Clus', 30500004, 30500027, 0.025)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (5, N'051111Clus', 30500004, 30500029, 0.45)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (6, N'051111Clus', 30500005, 30500006, 1)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (7, N'051111Clus', 30500007, 30500008, 1)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (8, N'051111Clus', 30500009, 30500010, 0.6)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (9, N'051111Clus', 30500009, 30500024, 0.4)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (10, N'051111Clus', 30500010, 30500011, 0.33333333333333331)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (11, N'051111Clus', 30500010, 30500017, 0.666666666666667)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (12, N'051111Clus', 30500011, 30500012, 1)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (13, N'051111Clus', 30500012, 30601745, 1)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (14, N'051111Clus', 30500013, 30500014, 1)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (15, N'051111Clus', 30500015, 30500016, 1)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (16, N'051111Clus', 30500017, 30601746, 1)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (17, N'051111Clus', 30500018, 30500019, 0.66666666666666663)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (18, N'051111Clus', 30500021, 30500022, 1)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (19, N'051111Clus', 30500022, 30500023, 1)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (20, N'051111Clus', 30500024, 30500025, 1)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (21, N'051111Clus', 30500025, 30500026, 0.5)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (22, N'051111Clus', 30500027, 30601747, 1)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (23, N'051111Clus', 30500029, 30500030, 0.5)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (24, N'051111Clus', 30601745, 30500013, 0.5)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (25, N'051111Clus', 30601745, 30500015, 0.5)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (26, N'051111Clus', 30601746, 30500018, 0.75)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (27, N'051111Clus', 30601746, 30500021, 0.25)
GO
INSERT [dbo].[tblttt] ([ID], [Work_ID], [From_ID], [To_ID], [Share]) VALUES (28, N'051111Clus', 30601747, 30500028, 1)
GO
SET IDENTITY_INSERT [dbo].[tblttt] OFF
GO
The output is this:
As clear from the screenshot, first group would be made having From_ID as 30500004 and To_ID as 30500005. The value of share should be 1 as this first row of this group. Next entry in this group would be row having From_ID as 30500005 and To_ID as 30500006 and share same as 1 of that row. Now, as there is no row with From_ID as 30500006, this group would end only and new group would again start having From_ID as 30500004 and To_ID as 30500007.
I tried following but its nowhere my requirement:
SELECT
TR.*
FROM tbltttT
LEFT JOIN tblttt TR
ON T.From_ID = TR.To_ID
WHERE T.work_id = '051111Clus' AND TR.work_id = '051111Clus'
So how can I achieve this?

I solved this by Looping instead of Recursive queries, starting from all the leaf nodes, then to their parent node till top node.

Related

Trying to insert data to multiple table with the last table `student` being the child table. Data is inserted to the other tables except the parent

BEGIN;
INSERT INTO `address` (`postal address`, `email`, `phone_number`) VALUES ('1527', 'tommydd#gmail.com', '0766452152');
INSERT INTO `bank` (`bank_number`, `bank_name`,`branch`) VALUES ('050002345678', 'Equity', 'Haniwa');
INSERT INTO `fees` (`perannum`, `fee_balance`) VALUES ('27000', '1500.34');
INSERT INTO `institution` (`Institution_name`, `course`, `form_study_year`, `adm_upi`, `type`) VALUES ('KU', 'Computer Science', '3rd Year', 'STT/B/01-003/2009', 'Public Day');
INSERT INTO `student` (`address_id`, `fees_id`, `bank_id`, `institution_id`, `first_name`, `middle_name`, `last_name`, `gender`, `date_of_birth`, `bc_no`, `parent`) VALUES ('LAST_INSERT_ID()', 'LAST_INSERT_ID()', 'LAST_INSERT_ID()', 'LAST_INSERT_ID()', 'Tommy', 'Gas', 'John', 'Male', '11/04/1999', '3868686', 'Both Alive');
COMMIT;

Order trigger (update) for inventory

I am still a beginner in mySQL. I have been trying to figure out a trigger for my project but can't come up with a solution. Here is what I am trying to do:
When an order is made I want a trigger to update the inventory. The bump here is that orders can have many products and those products are composed of different elements of the inventory. Here is how I tried it maybe it can help you understand the idea.
create trigger subtract_inv
after insert on order_details for each row
begin
update inventory
set Inv_qty = Inv_qty - (order_details.Order_details_qty * recipes.Requiered_qty)
where Products_Prod_ID = NEW.Products_Prod_ID and inventory.Inv_ID = recipes.Inventory_Inv_ID;
end$$
delimiter ;
Here are the 3 tables
-- -----------------------------------------------------
-- Table `McDo`.`Order_details`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `McDo`.`Order_details` (
`orders_Order_id` INT NOT NULL,
`Products_Prod_ID` INT NOT NULL,
`Order_details_qty` INT NULL,
PRIMARY KEY (`orders_Order_id`, `Products_Prod_ID`),
INDEX `fk_orders_has_Products_Products1_idx` (`Products_Prod_ID`
ASC) VISIBLE,
INDEX `fk_Order_details_orders1_idx` (`orders_Order_id` ASC)
VISIBLE,
CONSTRAINT `fk_orders_has_Products_Products1`
FOREIGN KEY (`Products_Prod_ID`)
REFERENCES `McDo`.`Products` (`Prod_ID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_Order_details_orders1`
FOREIGN KEY (`orders_Order_id`)
REFERENCES `McDo`.`Orders` (`Order_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `McDo`.`Inventory`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `McDo`.`Inventory` (
`Inv_ID` INT NOT NULL,
`Inv_type` VARCHAR(1) NOT NULL,
`Inv_name` VARCHAR(45) NULL,
`Inv_qty` INT NULL,
`Inv_price_unit` DECIMAL(20,2) NULL,
PRIMARY KEY (`Inv_ID`))
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `McDo`.`Recipes`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `McDo`.`Recipes` (
`Products_Prod_ID` INT NOT NULL,
`Inventory_Inv_ID` INT NOT NULL,
`Requiered_qty` INT NULL,
PRIMARY KEY (`Products_Prod_ID`, `Inventory_Inv_ID`),
INDEX `fk_Products_has_Inventory_Products1_idx` (`Products_Prod_ID` ASC)
VISIBLE,
INDEX `fk_Products_has_Inventory_Inventory1_idx` (`Inventory_Inv_ID`
ASC) VISIBLE,
CONSTRAINT `fk_Products_has_Inventory_Products1`
FOREIGN KEY (`Products_Prod_ID`)
REFERENCES `McDo`.`Products` (`Prod_ID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_Products_has_Inventory_Inventory1`
FOREIGN KEY (`Inventory_Inv_ID`)
REFERENCES `McDo`.`Inventory` (`Inv_ID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
and here a sample of the data
-- -----------------------------------------------------
-- Data for table `McDo`.`Recipes`
-- -----------------------------------------------------
START TRANSACTION;
USE `McDo`;
INSERT INTO `McDo`.`Recipes` (`Products_Prod_ID`, `Inventory_Inv_ID`, `Requiered_qty`) VALUES (301, 102, 3);
INSERT INTO `McDo`.`Recipes` (`Products_Prod_ID`, `Inventory_Inv_ID`, `Requiered_qty`) VALUES (301, 103, 2);
INSERT INTO `McDo`.`Recipes` (`Products_Prod_ID`, `Inventory_Inv_ID`, `Requiered_qty`) VALUES (301, 112, 1);
INSERT INTO `McDo`.`Recipes` (`Products_Prod_ID`, `Inventory_Inv_ID`, `Requiered_qty`) VALUES (301, 110, 1);
INSERT INTO `McDo`.`Recipes` (`Products_Prod_ID`, `Inventory_Inv_ID`, `Requiered_qty`) VALUES (301, 111, 2);
INSERT INTO `McDo`.`Recipes` (`Products_Prod_ID`, `Inventory_Inv_ID`, `Requiered_qty`) VALUES (301, 114, 1);
INSERT INTO `McDo`.`Recipes` (`Products_Prod_ID`, `Inventory_Inv_ID`, `Requiered_qty`) VALUES (301, 113, 1);
INSERT INTO `McDo`.`Recipes` (`Products_Prod_ID`, `Inventory_Inv_ID`, `Requiered_qty`) VALUES (301, 108, 1);
INSERT INTO `McDo`.`Recipes` (`Products_Prod_ID`, `Inventory_Inv_ID`, `Requiered_qty`) VALUES (302, 101, 2);
INSERT INTO `McDo`.`Recipes` (`Products_Prod_ID`, `Inventory_Inv_ID`, `Requiered_qty`) VALUES (302, 111, 2);
INSERT INTO `McDo`.`Recipes` (`Products_Prod_ID`, `Inventory_Inv_ID`, `Requiered_qty`) VALUES (302, 103, 2);
INSERT INTO `McDo`.`Recipes` (`Products_Prod_ID`, `Inventory_Inv_ID`, `Requiered_qty`) VALUES (302, 107, 1);
INSERT INTO `McDo`.`Recipes` (`Products_Prod_ID`, `Inventory_Inv_ID`, `Requiered_qty`) VALUES (302, 113, 1);
INSERT INTO `McDo`.`Recipes` (`Products_Prod_ID`, `Inventory_Inv_ID`, `Requiered_qty`) VALUES (302, 114, 1);
INSERT INTO `McDo`.`Recipes` (`Products_Prod_ID`, `Inventory_Inv_ID`, `Requiered_qty`) VALUES (302, 108, 1);
INSERT INTO `McDo`.`Recipes` (`Products_Prod_ID`, `Inventory_Inv_ID`, `Requiered_qty`) VALUES (302, 109, 1);
INSERT INTO `McDo`.`Recipes` (`Products_Prod_ID`, `Inventory_Inv_ID`, `Requiered_qty`) VALUES (301, 204, 1);
INSERT INTO `McDo`.`Recipes` (`Products_Prod_ID`, `Inventory_Inv_ID`, `Requiered_qty`) VALUES (302, 202, 1);
-- -----------------------------------------------------
-- Data for table `McDo`.`Inventory`
-- -----------------------------------------------------
START TRANSACTION;
USE `McDo`;
INSERT INTO `McDo`.`Inventory` (`Inv_ID`, `Inv_type`, `Inv_name`, `Inv_qty`, `Inv_price_unit`) VALUES (101, 'C', 'regular bun', 1000, 0.07);
INSERT INTO `McDo`.`Inventory` (`Inv_ID`, `Inv_type`, `Inv_name`, `Inv_qty`, `Inv_price_unit`) VALUES (102, 'C', 'sesame bun', 1000, 0.12);
INSERT INTO `McDo`.`Inventory` (`Inv_ID`, `Inv_type`, `Inv_name`, `Inv_qty`, `Inv_price_unit`) VALUES (103, 'C', 'beef patty', 1000, 0.35);
INSERT INTO `McDo`.`Inventory` (`Inv_ID`, `Inv_type`, `Inv_name`, `Inv_qty`, `Inv_price_unit`) VALUES (107, 'C', 'ketchup sachet', 5000, 0.02);
INSERT INTO `McDo`.`Inventory` (`Inv_ID`, `Inv_type`, `Inv_name`, `Inv_qty`, `Inv_price_unit`) VALUES (108, 'C', 'seasoning sachet', 5000, 0.01);
INSERT INTO `McDo`.`Inventory` (`Inv_ID`, `Inv_type`, `Inv_name`, `Inv_qty`, `Inv_price_unit`) VALUES (109, 'C', 'mustard sachet', 5000, 0.01);
INSERT INTO `McDo`.`Inventory` (`Inv_ID`, `Inv_type`, `Inv_name`, `Inv_qty`, `Inv_price_unit`) VALUES (110, 'C', 'big mac sauce sachet', 5000, 0.04);
INSERT INTO `McDo`.`Inventory` (`Inv_ID`, `Inv_type`, `Inv_name`, `Inv_qty`, `Inv_price_unit`) VALUES (111, 'C', 'cheese slice', 2000, 0.05);
INSERT INTO `McDo`.`Inventory` (`Inv_ID`, `Inv_type`, `Inv_name`, `Inv_qty`, `Inv_price_unit`) VALUES (112, 'C', 'precut letuce', 1500, 0.02);
INSERT INTO `McDo`.`Inventory` (`Inv_ID`, `Inv_type`, `Inv_name`, `Inv_qty`, `Inv_price_unit`) VALUES (113, 'C', 'precut onion', 1500, 0.01);
INSERT INTO `McDo`.`Inventory` (`Inv_ID`, `Inv_type`, `Inv_name`, `Inv_qty`, `Inv_price_unit`) VALUES (114, 'C', 'precut pickle', 1500, 0.01);
INSERT INTO `McDo`.`Inventory` (`Inv_ID`, `Inv_type`, `Inv_name`, `Inv_qty`, `Inv_price_unit`) VALUES (202, 'N', 'mc double wrapping', 1000, 0.01);
INSERT INTO `McDo`.`Inventory` (`Inv_ID`, `Inv_type`, `Inv_name`, `Inv_qty`, `Inv_price_unit`) VALUES (204, 'N', 'big mac box', 1000, 0.02);
and orders can look like:
1000,301,2;
1000,302,1;
1001,301,2;
1002,302,3;
You are allowed to use joins in an update query so perhaps this
delimiter $$
CREATE TRIGGER `subtract_inv` AFTER INSERT ON `order_details` FOR EACH ROW
begin
update inventory join
(select r.inventory_inv_id rinvid,new.order_details_qty * r.Requiered_qty adjustment
from recipes r join inventory i on i.inv_id = r.inventory_inv_id
where r.products_prod_id = new.products_prod_id) s
set inv_qty = inv_qty - s.adjustment
where inventory.Inv_ID = s.rinvid;
end $$
delimiter ;

Unable to Add More Than One Field in Table in MySQL

I'm trying to add a table in a MySQL database. The database is called "stocks". The odd thing I'm encountering is that while I can create the table, I can't add any fields to it other than the primary key.
Code is below. Please note that I can create the "person" table and all of its fields and populate all fields without a problem. The "quotes" table and "person_quotes" table can be created, too, but I cannot populate them with any fields other than the primary key. Anyone have any idea what's going on?
/* delete tables if they exist already - ensuring a clean db */
DROP TABLE IF EXISTS stocks.person CASCADE;
DROP TABLE IF EXISTS stocks.quotes CASCADE;
DROP TABLE IF EXISTS stocks.person_quotes CASCADE;
/** creates a table to store a list of persons */
CREATE TABLE stocks.person
(
person_ID INT PRIMARY KEY NOT NULL,
first_name VARCHAR(256) NOT NULL,
last_name VARCHAR(256) NOT NULL,
birth_date DATETIME NOT NULL
);
/* creates a table to store a list of quotes */
CREATE TABLE stocks.quotes
(
quotes_ID INT PRIMARY KEY NOT NULL,
symbol VARCHAR(256) NOT NULL,
quote_time DATETIME NOT NULL,
price DECIMAL NOT NULL
);
/** A list of people and their quotes */
CREATE TABLE stocks.person_quotes
(
person_quote_ID INT PRIMARY KEY NOT NULL,
person_id INT NOT NULL,
quotes_id INT NOT NULL,
FOREIGN KEY (person_id) REFERENCES person (person_ID),
FOREIGN KEY (quotes_id) REFERENCES quotes (quotes_ID)
);
/** add some sample data */
INSERT INTO quotes (quotes_ID,symbol,quote_time,price) VALUES (1, 'GOOG', '2018-09-21 00:00:01', 85);
INSERT INTO quotes (quotes_ID,symbol,quote_time,price) VALUES (2, 'GOOG', '2018-09-21 00:00:59', 95);
INSERT INTO quotes (quotes_ID,symbol,quote_time,price) VALUES (3, 'GOOG', '2018-09-21 01:00:01', 105);
INSERT INTO quotes (quotes_ID,symbol,quote_time,price) VALUES (4, 'GOOG', '2018-09-21 02:00:01', 115);
INSERT INTO quotes (quotes_ID,symbol,quote_time,price) VALUES (5, 'GOOG', '2018-09-21 03:00:01', 125);
INSERT INTO quotes (quotes_ID,symbol,quote_time,price) VALUES (6, 'GOOG', '2018-09-22 00:00:01', 135);
INSERT INTO quotes (quotes_ID,symbol,quote_time,price) VALUES (7, 'GOOG', '2018-09-22 01:00:01', 145);
INSERT INTO quotes (quotes_ID,symbol,quote_time,price) VALUES (8, 'GOOG', '2018-09-22 02:00:01', 155);
INSERT INTO quotes (quotes_ID,symbol,quote_time,price) VALUES (9, 'GOOG', '2018-09-22 03:00:01', 165);
INSERT INTO quotes (quotes_ID,symbol,quote_time,price) VALUES (10, 'GOOG', '2018-09-23 00:00:01', 175);
INSERT INTO quotes (quotes_ID,symbol,quote_time,price) VALUES (11, 'GOOG', '2018-09-24 00:00:01', 185);
INSERT INTO quotes (quotes_ID,symbol,quote_time,price) VALUES (12, 'GOOG', '2018-09-25 00:00:01', 195);
INSERT INTO quotes (quotes_ID,symbol,quote_time,price) VALUES (13, 'GOOG', '2018-09-26 00:00:01', 205);
INSERT INTO quotes (quotes_ID,symbol,quote_time,price) VALUES (14, 'GOOG', '2018-09-27 00:00:01', 215);
INSERT INTO quotes (quotes_ID,symbol,quote_time,price) VALUES (15, 'GOOG', '2018-09-28 00:00:01', 225);
INSERT INTO quotes (quotes_ID,symbol,quote_time,price) VALUES (16, 'GOOG', '2018-09-29 00:00:01', 235);
INSERT INTO quotes (quotes_ID,symbol,quote_time,price) VALUES (17, 'GOOG', '2018-09-30 00:00:01', 245);
INSERT INTO quotes (quotes_ID,symbol,quote_time,price) VALUES (18, 'GOOG', '2018-09-30 00:00:01', 255);
INSERT INTO quotes (quotes_ID,symbol,quote_time,price) VALUES (19, 'GOOG', '2018-10-01 00:00:01', 265);
INSERT INTO quotes (quotes_ID,symbol,quote_time,price) VALUES (20, 'GOOG', '2018-10-02 00:00:01', 275);
INSERT INTO person (person_ID,first_name,last_name,birth_date) VALUES (1, 'Drew', 'Hope', '1999/10/10');
INSERT INTO person (person_ID,first_name,last_name,birth_date) VALUES (2, 'Lang', 'Heckman', '1959/11/11');
INSERT INTO person (person_ID,first_name,last_name,birth_date) VALUES (3, 'Lucy', 'Jones', '2010/1/1');
INSERT INTO person (person_ID,first_name,last_name,birth_date) VALUES (4, 'Stew', 'Hammer', '1990/3/28');
INSERT INTO person (person_ID,first_name,last_name,birth_date) VALUES (5, 'Dan', 'Lane', '1986/4/18');
INSERT INTO person (person_ID,first_name,last_name,birth_date) VALUES (6, 'James', 'Marrese', '1915/10/18');
INSERT INTO person_quotes (person_quotes_ID, person_id, quotes_id) VALUES (1, 1, 2);
INSERT INTO person_quotes (person_quotes_ID, person_id, quotes_id) VALUES (2, 1, 1);
INSERT INTO person_quotes (person_quotes_ID, person_id, quotes_id) VALUES (3, 2, 1);
INSERT INTO person_quotes (person_quotes_ID, person_id, quotes_id) VALUES (4, 3, 1);
INSERT INTO person_quotes (person_quotes_ID, person_id, quotes_id) VALUES (5, 3, 3);
INSERT INTO person_quotes (person_quotes_ID, person_id, quotes_id) VALUES (6, 3, 4);
INSERT INTO person_quotes (person_quotes_ID, person_id, quotes_id) VALUES (7, 4, 7);

Needing assistance with counting the most different books

Which customer(s) ordered the most different books? Display the customer id and include ties. This is not talking about the quantity of books ordered. For example, suppose my only orders are Customer 1 ordered 400 copies of book_id 34 Customer 2 ordered 2 copies of book_id 62 and 3 copies of book_id 29 Customer 1 ordered a larger quantity of books but customer 2 ordered more different books. The query should - in this case- return customer 2:
Here is my attempted solution. Not sure how to solve this one:
SELECT cust_id
FROM a_bkorders.customers
WHERE cust_id IN
(
SELECT cust_id
FROM a_bkorders.order_headers
Join a_bkorders.order_details using (order_id)
GROUP BY cust_id
HAVING count(book_id) <=
(
SELECT MAX(numBooks)
FROM (
SELECT cust_id
, count(book_id) AS numBooks
Join a_bkorders.order_details using (order_id)
FROM a_bkorders.order_headers
GROUP BY cust_id
) t
)
)ORDER BY cust_id;
Here are the tables:
-- create customers
create table a_bkorders.customers (
cust_id integer not null
, cust_name_last varchar(20) not null
, cust_name_first varchar(20) null
, cust_state char(2) not null
, cust_postal_code char(10) not null
, cust_acct_opened date not null
, constraint bk_cust_pk primary key (cust_id)
, constraint bk_cust_id_range check (cust_id > 1000)
, constraint bk_cust_acct_opened_ck check (cust_acct_opened >= '1975-01-01' )
)engine = INNODB;
-- create order_headers
create table a_bkorders.order_headers (
order_id integer not null
, order_date date not null
, cust_id integer not null
, constraint bk_orders_pk primary key (order_id)
, constraint bk_orders_cust_fk foreign key(cust_id)
references a_bkorders.customers(cust_id)
, constraint bk_order_id_range check (order_id > 100)
, constraint bk_order_date_ck check (order_date >= '2000-01-01')
)engine = INNODB;
-- create order_details
create table a_bkorders.order_details (
order_id integer not null
, order_line integer not null
, book_id integer not null
, quantity integer not null
, order_price numeric(6,2) not null
, constraint bk_orderline_pk primary key (order_id, order_line)
, constraint bk_orderline_order_fk foreign key (order_id)
references a_bkorders.order_headers(order_id) on delete cascade
, constraint bk_orderline_book_fk foreign key (book_id )
references a_bkinfo.books(book_id)
, constraint bk_quantity_ck check (quantity > 0)
, constraint bk_ordprice_ck check (order_price >= 0)
)engine = INNODB;
Here are the inserts:
-- customers
insert into a_bkorders.customers values (208950, 'Adams', 'Samuel', 'MA', '02106', '1996-04-15' );
insert into a_bkorders.customers values (200368, 'Blake', 'William', 'CA', '95959', '1997-07-15' );
insert into a_bkorders.customers values (258595, 'Jobs', 'Peter', 'MA', '02575', '1997-01-09' );
insert into a_bkorders.customers values (263119, 'Jones', null, 'IL', '62979', '1997-03-02' );
insert into a_bkorders.customers values (224038, 'Austin', 'Pat', 'CA', '95900', '1997-08-02' );
insert into a_bkorders.customers values (255919, 'Milton', 'John', 'NJ', '08235', '2011-05-31' );
insert into a_bkorders.customers values (211483, 'Carroll', 'Lewis', 'CA', '94203', '1998-08-08' );
insert into a_bkorders.customers values (221297, 'Dodgson', 'Charles', 'MI', '49327', '2001-05-06' );
insert into a_bkorders.customers values (261502, 'Hawthorne', 'Nathaniel', 'MA', '02297', '2001-10-12' );
insert into a_bkorders.customers values (212921, 'Books on Tap', NULL, 'CA', '94112', '2002-01-06' );
insert into a_bkorders.customers values (260368, 'Muller', 'Jonathan', 'IL', '62885', '2005-12-15' );
insert into a_bkorders.customers values (259969, 'Carlsen', 'Benny', 'NJ', '08505', '2011-07-12' );
insert into a_bkorders.customers values (239427, 'Marksa', 'Anna', 'NJ', '08495', '2011-02-28' );
insert into a_bkorders.customers values (296598, 'Collins', 'Douglas', 'MO', '65836', '2005-04-25' );
insert into a_bkorders.customers values (276381, 'Collins', 'Douglas', 'OH', '22451', '2005-02-08' );
insert into a_bkorders.customers values (234138, 'Keats', 'John', 'IL', '61500', '2006-04-30' );
insert into a_bkorders.customers values (267780, 'Shelly', 'Mary', 'CA', '94100', '2010-10-02' );
insert into a_bkorders.customers values (290298, 'Swift', 'Jonathan', 'MI', '49201', '2010-10-12' );
insert into a_bkorders.customers values (226656, 'Randall', 'Randell', 'NJ', '08251', '2011-08-08' );
insert into a_bkorders.customers values (222477, 'Rossetti', 'Christina', 'MI', '49742', '2011-07-11' );
insert into a_bkorders.customers values (227105, 'Kafka', 'Franz', 'MA', '02297', '2010-12-31' );
insert into a_bkorders.customers values (202958, 'Denver', null, 'IL', '60405', '2011-01-15' );
insert into a_bkorders.customers values (218709, 'Bonnard', 'Paul', 'MA', '02558', '2005-11-15' );
insert into a_bkorders.customers values (217796, 'Anders', null, 'IL', '62505', '2011-03-30' );
insert into a_bkorders.customers values (272787, 'Carlson', 'Ben', 'IL', '62505', '2011-05-05' );
insert into a_bkorders.customers values (234709, 'Brahms', 'Johnnie', 'MA', '02558', '2012-01-15' );
insert into a_bkorders.customers values (217002, 'Grieg', 'Edvard', 'IL', '62329', '2012-02-29' );
insert into a_bkorders.customers values (272611, 'Jarrett', 'Keith', 'IL', '62329', '2011-11-11' );
insert into a_bkorders.customers values (299099, 'Sam', 'Dave', 'CA', '94141', '2011-01-01' );
insert into a_bkorders.customers values (259906, 'Capybara', 'Wile E.', 'CA', '94132', '2012-01-05' );
insert into a_bkorders.customers values (259907, 'Hedge', 'Mr.', 'CA', '94132', '2011-09-05' );
insert into a_bkorders.customers values (282716, 'Biederbecke','Dwight', 'PA', '18106', '2013-01-01' );
insert into a_bkorders.customers values (287261, 'Biederbecke','Bix', 'PA', '18106', '2012-01-01' );
insert into a_bkorders.customers values (226275, 'Dalrymple','Jack', 'SD', '57216', '2013-01-01' );
insert into a_bkorders.customers values (228175, 'Cardin','Benjamin', 'MD', '20609', '2013-04-02' );
insert into a_bkorders.customers values (228275, 'Mikulski','Barbara', 'MD', '21203', '2013-04-04' );
insert into a_bkorders.customers values (228352, 'Edwards','Donna', 'MD', '21205', '2013-06-08' );
-- orders and order_details
/* July 2011 */
Insert into a_bkorders.order_headers values(21841, '2011-07-02', 267780);
Insert into a_bkorders.order_details values(21841, 1, 1448, 50, 25.00);
Insert into a_bkorders.order_headers values(21850, '2011-07-02', 261502);
Insert into a_bkorders.order_details values(21850, 1, 1162, 1, 30.49);
Insert into a_bkorders.order_details values(21850, 2, 1109, 1, 25.00);
Insert into a_bkorders.order_headers values(2045, '2011-07-18', 267780);
Insert into a_bkorders.order_details values(2045, 1, 1894, 1, 35.99);
Insert into a_bkorders.order_headers values(2200, '2011-07-18', 261502);
Insert into a_bkorders.order_details values(2200, 1, 1200, 5, 16.33);
Insert into a_bkorders.order_details values(2200, 2, 1180, 5, 45.99);
Insert into a_bkorders.order_details values(2200, 3, 1128, 5, 46.20);
/* Sep 2011 */
Insert into a_bkorders.order_headers values(22909, '2011-09-25', 239427);
Insert into a_bkorders.order_details values(22909, 1, 1104, 5, 45.00);
Insert into a_bkorders.order_headers values(22910, '2011-09-25', 218709);
Insert into a_bkorders.order_details values(22910, 1, 1678, 5, 49.99);
Insert into a_bkorders.order_details values(22910, 2, 1162, 5, 35.00);
Insert into a_bkorders.order_headers values(32997, '2011-09-22', 239427);
Insert into a_bkorders.order_details values(32997, 1, 1948, 5, 40.94);
Insert into a_bkorders.order_details values(32997, 2, 1199, 5, 18.39);
Insert into a_bkorders.order_details values(32997, 3, 1457, 5, 53.99);
Insert into a_bkorders.order_details values(32997, 4, 1133, 5, 18.15);
Insert into a_bkorders.order_details values(32997, 5, 1894, 5, 36.79);
Insert into a_bkorders.order_headers values(32998, '2011-09-22', 261502);
Insert into a_bkorders.order_details values(32998, 1, 2006, 3, 20.00);
Insert into a_bkorders.order_headers values(41005, '2011-09-28', 290298);
Insert into a_bkorders.order_details values(41005, 1, 1142, 2, 42.45);
Insert into a_bkorders.order_details values(41005, 2, 1107, 4, 21.50);
Insert into a_bkorders.order_headers values(41006, '2011-09-28', 267780);
Insert into a_bkorders.order_details values(41006, 1, 1142, 10, 42.95);
Insert into a_bkorders.order_headers values(42899, '2011-09-29', 261502);
Insert into a_bkorders.order_details values(42899, 1, 1128, 5, 25.00);
Insert into a_bkorders.order_details values(42899, 2, 1103, 1 , 10.95);
/* Oct 2011 */
Insert into a_bkorders.order_headers values(21254, '2011-10-23', 263119);
Insert into a_bkorders.order_details values(21254, 2, 2008, 10, 46.95);
Insert into a_bkorders.order_details values(21254, 3, 2007, 10, 39.00);
Insert into a_bkorders.order_headers values(21255, '2011-10-28', 267780);
Insert into a_bkorders.order_details values(21255, 1, 1101, 5, 59.99);
Insert into a_bkorders.order_details values(21255, 2, 1142, 5, 39.00);
Insert into a_bkorders.order_details values(21255, 3, 1162, 2, 35.00);
Insert into a_bkorders.order_headers values(21261, '2011-10-28', 200368);
Insert into a_bkorders.order_details values(21261, 1, 1142, 100, 34.95);
Insert into a_bkorders.order_details values(21261, 2, 1128, 50, 46.95);
Insert into a_bkorders.order_details values(21261, 3, 2001, 100, 39.00);
Insert into a_bkorders.order_headers values(32905, '2011-10-02', 259906);
Insert into a_bkorders.order_details values(32905, 1, 2028, 1, 58.00);
Try this:
SELECT c.cust_id, COUNT(DISTINCT od.book_id) bookCnt
FROM a_bkorders.customers c
INNER JOIN a_bkorders.order_headers oh ON c.cust_id = oh.cust_id
INNER JOIN a_bkorders.order_details od ON oh.order_id = od.order_id
GROUP BY c.cust_id
ORDER BY bookCnt DESC

MySQL Query Optimization - Avoiding Subqueries

I need to update some rows in my table, for simplicity called "three".
I select the columns to update with this query:
SELECT one.id
FROM one
JOIN `two` ON ( one.id = two.page )
JOIN `three` ON ( one.id = three.item )
WHERE two.level = 1
AND two.item = (SELECT item FROM two WHERE page = 5 AND level = 1 )
AND three.position > (SELECT position FROM three WHERE item = 5 )
ORDER BY three.position
Now I call an update query with id's I get.
Is there any chance to eliminate the subqueries?
Edit (after Melanie's comment):
Table "one":
|id|text|
Table "two":
|id|item|page|level|
Table "three":
|item|position|
So when I run the query
SELECT item FROM two WHERE page = 5 AND level = 1
It will return f.ex 1 and the final WHERE clause will be:
two.item = 1 AND two.level = 1
Which is not the same as:
two.level = 1 and two.page = 5
I have the table one - some text with some one.id. I need to update all items from table three which has higher position than my item (f.ex. id = 5) have. But those items should also have the same two.item in table two, where two.page = one.id and level = 1
I am sorry for a poor description.
You should be able to replace those subqueries by joins:
SELECT one.id
FROM one
JOIN `two2` ON (two2.page = 5 AND two2.level = 1)
JOIN `two` ON ( one.id = two.page AND two.item = two2.item )
JOIN `three2` ON ( three.item = 5)
JOIN `three` ON ( one.id = three.item AND three.position > three2.position)
WHERE two.level = 1
ORDER BY three.position
#TheVedge is interesting solution but does not produce the same result as your query
I suggest to avoid duplicate the same table also with a view so a little correction
Another correction is three2.item=5
I suggest to use in subquery limit 0,1 so never return more then one element
SELECT one.id
FROM one
JOIN `two` AS TWO2 ON (two2.page = 5 AND two2.level = 1)
JOIN `two` ON ( one.id = two.page AND two.item = two2.item )
JOIN `three` AS THREE2 ON ( three2.item = 5)
JOIN `three` ON ( one.id = three.item AND three.position > three2.position)
WHERE two.level = 1
ORDER BY three.position
Remember that you are not doing the same thing with this query.
Try this
CREATE TABLE `one` (
`id` INT(10) NULL DEFAULT NULL,
`text` VARCHAR(50) NULL DEFAULT NULL
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
_
CREATE TABLE `three` (
`item` INT(10) NULL DEFAULT NULL,
`position` INT(10) NULL DEFAULT NULL
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
_
CREATE TABLE `two` (
`id` INT(10) NULL DEFAULT NULL,
`item` INT(10) NULL DEFAULT NULL,
`page` INT(10) NULL DEFAULT NULL,
`level` INT(10) NULL DEFAULT NULL
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
_
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (1, 1, 5, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (3, 3, 5, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (4, 4, 5, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (5, 5, 5, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (6, 6, 5, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (7, 7, 5, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (8, 8, 5, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (9, 9, 5, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (2, 2, 5, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (10, 2, 1, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (11, 1, 1, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (13, 3, 1, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (14, 4, 1, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (15, 5, 1, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (16, 6, 1, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (17, 7, 1, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (18, 8, 1, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (19, 9, 1, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (20, 2, 2, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (21, 1, 2, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (23, 3, 2, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (24, 4, 2, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (25, 5, 2, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (26, 6, 2, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (27, 7, 2, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (28, 8, 2, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (29, 9, 2, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (30, 2, 3, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (31, 1, 3, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (33, 3, 3, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (34, 4, 3, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (35, 5, 3, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (36, 6, 3, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (37, 7, 3, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (38, 8, 3, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (39, 9, 3, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (40, 2, 4, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (41, 1, 4, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (42, 3, 4, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (43, 4, 4, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (44, 5, 4, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (45, 6, 4, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (46, 7, 4, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (47, 8, 4, 1);
INSERT INTO `two` (`id`, `item`, `page`, `level`) VALUES (48, 9, 4, 1);
-
INSERT INTO `three` (`item`, `position`) VALUES (1, 1);
INSERT INTO `three` (`item`, `position`) VALUES (2, 1);
INSERT INTO `three` (`item`, `position`) VALUES (3, 1);
INSERT INTO `three` (`item`, `position`) VALUES (4, 1);
INSERT INTO `three` (`item`, `position`) VALUES (5, 0);
INSERT INTO `three` (`item`, `position`) VALUES (6, 1);
INSERT INTO `three` (`item`, `position`) VALUES (7, 1);
INSERT INTO `three` (`item`, `position`) VALUES (8, 1);
INSERT INTO `three` (`item`, `position`) VALUES (9, 1);
INSERT INTO `three` (`item`, `position`) VALUES (10, 1);
INSERT INTO `three` (`item`, `position`) VALUES (11, 1);
INSERT INTO `three` (`item`, `position`) VALUES (12, 1);
_
INSERT INTO `one` (`id`, `text`) VALUES (1, 'A');
INSERT INTO `one` (`id`, `text`) VALUES (2, 'B');
INSERT INTO `one` (`id`, `text`) VALUES (3, 'C');
INSERT INTO `one` (`id`, `text`) VALUES (4, 'D');
INSERT INTO `one` (`id`, `text`) VALUES (5, 'E');
INSERT INTO `one` (`id`, `text`) VALUES (6, 'F');
INSERT INTO `one` (`id`, `text`) VALUES (7, 'G');
_
SELECT
one.id, one.text
,two.id,two.item,two.page,two.level
,three.item,three.position
FROM one
JOIN `two` ON ( one.id = two.page )
JOIN `three` ON ( one.id = three.item )
WHERE two.level = 1
AND two.item = (SELECT item FROM two WHERE page = 5 AND level = 1 limit 0,1 )
AND three.position > (SELECT position FROM three WHERE item = 5 limit 0,1 )
ORDER BY three.position
SELECT
one.id, one.text
,two.id,two.item,two.page,two.level
,three.item,three.position
FROM one
JOIN `two` AS TWO2 ON (two2.page = 5 AND two2.level = 1)
JOIN `two` ON ( one.id = two.page AND two.item = two2.item )
JOIN `three` AS THREE2 ON ( three2.item = 5)
JOIN `three` ON ( one.id = three.item AND three.position > three2.position)
WHERE two.level = 1
ORDER BY three.position
With original query you made a select of specific element in TheVedge solution you are joining more data
So result depend on what you select
Another useful analysis is http://dev.mysql.com/doc/refman/5.0/en/show-profile.html and Explain
Show Profile show that at the first run
your original query does
Status Duration
starting 0.000039
checking query cache for query 0.000144
Opening tables 0.000032
System lock 0.000007
Table lock 0.000061
init 0.000054
optimizing 0.000314
statistics 0.000021
preparing 0.000051
Creating tmp table 0.000084
executing 0.000004
Copying to tmp table 0.000063
optimizing 0.000008
statistics 0.000019
preparing 0.000009
executing 0.000004
Sending data 0.000054
optimizing 0.000008
statistics 0.000007
preparing 0.000009
executing 0.000003
Sending data 0.000126
Sorting result 0.000030
Sending data 0.000025
end 0.000004
removing tmp table 0.000011
end 0.000005
query end 0.000004
freeing items 0.000101
storing result in query cache 0.000008
logging slow query 0.000003
cleaning up 0.000006
Proposed query does
Status Duration
starting 0.000036
checking query cache for query 0.000122
Opening tables 0.000030
System lock 0.000008
Table lock 0.000064
init 0.000046
optimizing 0.000028
statistics 0.000026
preparing 0.000072
Creating tmp table 0.000086
executing 0.000005
Copying to tmp table 0.001081
Sorting result 0.000040
Sending data 0.000056
end 0.000005
removing tmp table 0.000010
end 0.000005
query end 0.000004
freeing items 0.000108
storing result in query cache 0.000007
logging slow query 0.000003
cleaning up 0.000005
So when you have full data you can try to evalute better the response of both query