I'm new to MySQL and trying to select the total number of orders for each user in the orders table. Also, I'm trying to order the results by most orders to the least orders.
This is what I have for order table
CREATE TABLE `order` (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
created TIMESTAMP NOT NULL DEFAULT NOW(),
user_id INTEGER NOT NULL,
FOREIGN KEY (user_id) REFERENCES user(id) ON DELETE RESTRICT
);
And this is what I have for user table
CREATE TABLE user (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
email VARCHAR(255) NOT NULL UNIQUE,
`password` VARCHAR(255) NOT NULL,
first_name VARCHAR(255),
last_name VARCHAR(255),
created TIMESTAMP NOT NULL DEFAULT NOW()
);
I have referenced other resources and tried the following, but I'm getting an error..Not sure how I can go about it?
SELECT COUNT(DISTINCT order_id) AS user_id
FROM `order`
GROUP BY user_id
this will
group by user_id
then count all lines
you will get one line per user_id with the count
ps: distinct is useless because order.id is an autoincrement key.
select user_id, count(*) as nb
from order
group by user_id
Or this if you want users with no orders included.
you need to start from user table, join all related orders, and basically do the same counting and grouping as before.
select u.id, count(*) as nb
from user as u
left join `order` as o on o.user_id = u.id
group by u.id
I want to delete some rows in a table. However the delete condition is not direct.This is just 1 table CUSTOMER:
CREATE TABLE customer (
CUST_ID int(11) NOT NULL AUTO_INCREMENT,
PRODUCT_CODE varchar(50) NOT NULL,
USER_NAME varchar(150) NOT NULL,
PRIMARY KEY (CUST_ID)
) ENGINE=InnoDB AUTO_INCREMENT=2455046 DEFAULT CHARSET=latin1;
Here is what works for me:
select cust_id from CUSTOMER where user_name = '20012';
Then use the resulting cust_id in the following DELETE ($cust_id is result of query 1)
delete from CUSTOMER where cust_id = $cust_id
Note: This can only delete one user_name . Also I want to do this in 1 query, not 2.
CUSTOMER t1
LEFT JOIN (
SELECT
cust_id id
FROM
CUSTOMER
where
user_name IN ('20012', '20013', '20014')
) t2 ON t1.cust_id = t2.id
The above apparently did not work.
You are unnecessarily complicating the logic. Instead of first getting all the customer id(s), for the given user_name values, you could simply filter on the user_name values. It is simply this:
DELETE FROM CUSTOMER WHERE user_name IN ('20012', '20013', '20014')
I have a table as follows for tracking employee daily entry. An employee can has multiple check in and out a day.
Is there a way to display in a way such that each record has the EmployeeID and respective earliest CheckIn and latest CheckOut of each day to summarize the record.
CREATE TABLE IF NOT EXISTS `PhyMeS_schema`.`DailyEntry` (
`EmployeeID` VARCHAR(10) NOT NULL,
`CheckIn` DATETIME NOT NULL,
`CheckOut` DATETIME NULL,
PRIMARY KEY (`EmployeeID`, `CheckIn`),
CONSTRAINT `fk_dailyEntry_EmployeeID`
FOREIGN KEY (`EmployeeID`)
REFERENCES `PhyMeS_schema`.`Employee` (`EmployeeID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
You should be able to do this with a simple GROUP BY on EmployeeID and DATE(CheckIn), like this:
SELECT
EmployeeID
, DATE(CheckIn) AS the_date
, MIN(CheckIn) AS min_checkin
, MAX(CheckOut) AS max_checkout
FROM DailyEntry
GROUP BY EmployeeID, DATE(CheckIn)
Note: this query assumes that all checkouts happen on the same day as their corresponding check-ins. In other words, nobody is inside on midnight. If you need to deal with night shifts, the query becomes more complex:
SELECT EmployeeID, the_date, MIN(min_checkin), MAX(max_checkout)
FROM (
SELECT EmployeeID, DATE(CheckIn) AS the_date, MIN(CheckIn) AS min_checkin, null as max_checkout
FROM DailyEntry
GROUP BY EmployeeID, DATE(CheckIn)
UNION ALL
SELECT EmployeeID, DATE(CheckOut) AS the_date, null AS min_checkin, MAX(CheckOut) as max_checkout
FROM DailyEntry
GROUP BY EmployeeID, DATE(CheckOut)
) GROUP BY EmployeeID, the_date
In my db I've a table (t1) with this structure
CREATE TABLE IF NOT EXISTS 't1' (
'id_ric' int(11) NOT NULL AUTO_INCREMENT,
'id_tipoins' decimal(1,0) NOT NULL,
'datains' timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY ('id_ric')
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
I create a view to count all record grouped by id_user in this way
CREATE VIEW view_users_app
AS
SELECT id_user, MAX(datains) last_datains, COUNT(*) totalCount
FROM t1
GROUP BY id_user
Now I'd like also count where id_tipoins = 1 and id_tipoins = 2 (grouped by id_user).
It's possible to do? How could I do this? Thanks
CREATE VIEW view_users_app
AS
SELECT id_user,
MAX(datains) last_datains,
COUNT(*) totalCount,
sum(id_tipoins = 1) as p1,
sum(id_tipoins = 2) as p2
FROM t1
GROUP BY id_user
I am trying to insert a new row and set the customer_id with max()+1. The reason for this is the table already has a auto_increatment on another column named id and the table will have multiple rows with the same customer_id.
With this:
INSERT INTO customers
( customer_id, firstname, surname )
VALUES
((SELECT MAX( customer_id ) FROM customers) +1, 'jim', 'sock')
...I keep getting the following error:
#1093 - You can't specify target table 'customers' for update in FROM clause
Also how would I stop 2 different customers being added at the same time and not having the same customer_id?
You can use the INSERT ... SELECT statement to get the MAX()+1 value and insert at the same time:
INSERT INTO
customers( customer_id, firstname, surname )
SELECT MAX( customer_id ) + 1, 'jim', 'sock' FROM customers;
Note: You need to drop the VALUES from your INSERT and make sure the SELECT selected fields match the INSERT declared fields.
Correct, you can not modify and select from the same table in the same query. You would have to perform the above in two separate queries.
The best way is to use a transaction but if your not using innodb tables then next best is locking the tables and then performing your queries. So:
Lock tables customers write;
$max = SELECT MAX( customer_id ) FROM customers;
Grab the max id and then perform the insert
INSERT INTO customers( customer_id, firstname, surname )
VALUES ($max+1 , 'jim', 'sock')
unlock tables;
Use alias name for the inner query like this
INSERT INTO customers
( customer_id, firstname, surname )
VALUES
((SELECT MAX( customer_id )+1 FROM customers cust), 'sharath', 'rock')
SELECT MAX(col) +1 is not safe -- it does not ensure that you aren't inserting more than one customer with the same customer_id value, regardless if selecting from the same table or any others. The proper way to ensure a unique integer value is assigned on insertion into your table in MySQL is to use AUTO_INCREMENT. The ANSI standard is to use sequences, but MySQL doesn't support them. An AUTO_INCREMENT column can only be defined in the CREATE TABLE statement:
CREATE TABLE `customers` (
`customer_id` int(11) NOT NULL AUTO_INCREMENT,
`firstname` varchar(45) DEFAULT NULL,
`surname` varchar(45) DEFAULT NULL,
PRIMARY KEY (`customer_id`)
)
That said, this worked fine for me on 5.1.49:
CREATE TABLE `customers` (
`customer_id` int(11) NOT NULL DEFAULT '0',
`firstname` varchar(45) DEFAULT NULL,
`surname` varchar(45) DEFAULT NULL,
PRIMARY KEY (`customer_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1$$
INSERT INTO customers VALUES (1, 'a', 'b');
INSERT INTO customers
SELECT MAX(customer_id) + 1, 'jim', 'sock'
FROM CUSTOMERS;
insert into table1(id1) select (max(id1)+1) from table1;
Use table alias in subquery:
INSERT INTO customers
( customer_id, firstname, surname )
VALUES
((SELECT MAX( customer_id ) FROM customers C) +1, 'jim', 'sock')
None of the about answers works for my case. I got the answer from here, and my SQL is:
INSERT INTO product (id, catalog_id, status_id, name, measure_unit_id, description, create_time)
VALUES (
(SELECT id FROM (SELECT COALESCE(MAX(id),0)+1 AS id FROM product) AS temp),
(SELECT id FROM product_catalog WHERE name="AppSys1"),
(SELECT id FROM product_status WHERE name ="active"),
"prod_name_x",
(SELECT id FROM measure_unit WHERE name ="unit"),
"prod_description_y",
UNIX_TIMESTAMP(NOW())
)
Your sub-query is just incomplete, that's all. See the query below with my additions:
INSERT INTO customers ( customer_id, firstname, surname )
VALUES ((SELECT MAX( customer_id ) FROM customers) +1), 'jim', 'sock')
You can't do it in a single query, but you could do it within a transaction. Do the initial MAX() select and lock the table, then do the insert. The transaction ensures that nothing will interrupt the two queries, and the lock ensures that nothing else can try doing the same thing elsewhere at the same time.
We declare a variable 'a'
SET **#a** = (SELECT MAX( customer_id ) FROM customers) +1;
INSERT INTO customers
( customer_id, firstname, surname )
VALUES
(**#a**, 'jim', 'sock')
This is select come insert sequel.
I am trying to get serial_no maximum +1 value and its giving correct value.
SELECT MAX(serial_no)+1 into #var FROM sample.kettle;
Insert into kettle(serial_no,name,age,salary) values (#var,'aaa',23,2000);