group conversation by users mysql select for messages - mysql

Table:
CREATE TABLE `messages` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`from_user_id` int(11) unsigned NOT NULL,
`to_user_id` int(11) unsigned NOT NULL,
`seen` tinyint(1) NOT NULL DEFAULT '0',
`sent` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`message` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `messages` (`id`, `from_user_id`, `to_user_id`, `seen`, `sent`, `message`)
VALUES
(1,2,1,0,'2013-11-06 11:05:42','Hello!'),
(2,1,2,0,'2013-11-06 11:05:52','Hello you too!'),
(3,3,1,0,'2013-11-06 11:06:08','Whats up?'),
(4,1,3,0,'2013-11-06 11:06:27','Not much');
I would put this in sqlfiddle but it is down for me, I cannot access it last 32 hours.
I've searched SO and found several related topics, but with different grouping requirements so I could not apply them to my project.
For the query, I know current user id and target user id, and based on this I want query to return all conversation of these two users ordered by date.
I was thinking something like:
SELECT message FROM messages WHERE from_user_id = 1 OR to_user_id = 1 [but where do I limit this query to target user 3?]
In other words I want to select:
(3,3,1,0,'2013-11-06 11:06:08','Whats up?')
(4,1,3,0,'2013-11-06 11:06:27','Not much')
For user 1, conversation with user 3. All of it.

SELECT message FROM messages
WHERE 1 in (from_user_id,to_user_id) and 3 in (from_user_id,to_user_id)

Related

MYSQL calculate volume from raw material units on raw materials in stock

I'm trying to figure out the calculation for finding the stock required and also display the volume output if it cant reach the max tresshold in this case volume '1000'.
I will try my best to explain it as plain as possible. (tables and columns are in dutch)
Example:
To produce a volume of 1000 I need multiple raw materials. The raw materials have different totals to go in the 'cooking pot' (and to reach 1000, aqua is added but thats a side note).
1000 is the base for calculating the numbers in the table receptgrondstoffen
First I have the table with the recipe called 'naam' (name)
table: recepten
CREATE TABLE `recepten` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`administratieid` int(11) NOT NULL DEFAULT 0,
`omzetgroepid` int(11) NOT NULL DEFAULT 0,
`artikelgroepid` int(11) NOT NULL DEFAULT 0,
`artikelnummer` int(11) NOT NULL DEFAULT 0 COMMENT 'gevuld vanuit snelstart',
`factornummer` varchar(20) NOT NULL,
`eannummer` varchar(20) NOT NULL,
`naam` varchar(255) NOT NULL,
`notitie` mediumtext NOT NULL,
`volume` decimal(10,5) NOT NULL DEFAULT 0.00000,
`onderzoek` int(1) NOT NULL DEFAULT 0,
`viscositeit` varchar(50) NOT NULL,
`phwaarde` varchar(50) NOT NULL,
`dichtheid` varchar(50) NOT NULL,
`thtmaanden` int(11) NOT NULL DEFAULT 0,
`voorraadcontrole` int(1) NOT NULL DEFAULT 0,
`drempelwaarde` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;
INSERT INTO `recepten` (`id`,`administratieid`,`omzetgroepid`,`artikelgroepid`,`artikelnummer`,`factornummer`,`eannummer`,`naam`,`notitie`,`volume`,`onderzoek`,`viscositeit`,`phwaarde`,`dichtheid`,`thtmaanden`,`voorraadcontrole`,`drempelwaarde`) VALUES (1,0,0,702,300001,'122','','test','test',1000.00000,1,'1','2','3',36,0,1);
INSERT INTO `recepten` (`id`,`administratieid`,`omzetgroepid`,`artikelgroepid`,`artikelnummer`,`factornummer`,`eannummer`,`naam`,`notitie`,`volume`,`onderzoek`,`viscositeit`,`phwaarde`,`dichtheid`,`thtmaanden`,`voorraadcontrole`,`drempelwaarde`) VALUES (2,0,0,704,300002,'1234','','test1','test',1000.00000,1,'1','2','3',36,0,100);
Second tables are the recipe items that go into the 'cooking pot'. There are 2 raw material lines. Both have a number of 100 so for each volume of 1000, 100 units from both are required. If I change the volume to 100 then 10 units from both are required.
table: receptgrondstoffen
CREATE TABLE `receptgrondstoffen` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`receptid` int(11) NOT NULL DEFAULT 0,
`grondstofid` int(11) NOT NULL DEFAULT 0,
`aantal` decimal(10,5) NOT NULL DEFAULT 0.00000,
`percentage` decimal(10,5) NOT NULL DEFAULT 0.00000,
UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
INSERT INTO `receptgrondstoffen` (`id`,`receptid`,`grondstofid`,`aantal`,`percentage`) VALUES (2,1,1,100.00000,10.00000);
INSERT INTO `receptgrondstoffen` (`id`,`receptid`,`grondstofid`,`aantal`,`percentage`) VALUES (3,1,2,100.00000,10.00000);
The 'grondstofbatch' tables is the raw material quantity that's been bought
Table: grondstofbatch
CREATE TABLE `grondstofbatch` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`grondstofid` int(11) NOT NULL DEFAULT 0,
`leveranciersid` int(11) NOT NULL DEFAULT 0,
`batchnummer` varchar(50) NOT NULL,
`datum` int(10) NOT NULL DEFAULT 0,
`thtdatum` int(10) NOT NULL DEFAULT 0,
`voorraad` int(11) NOT NULL DEFAULT 0,
UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
INSERT INTO `grondstofbatch` (`id`,`grondstofid`,`leveranciersid`,`batchnummer`,`datum`,`thtdatum`,`voorraad`) VALUES (1,1,4,'1224-4',1662626077,1665266400,100);
INSERT INTO `grondstofbatch` (`id`,`grondstofid`,`leveranciersid`,`batchnummer`,`datum`,`thtdatum`,`voorraad`) VALUES (2,1,3,'#34423',1662626904,1663970400,300);
INSERT INTO `grondstofbatch` (`id`,`grondstofid`,`leveranciersid`,`batchnummer`,`datum`,`thtdatum`,`voorraad`) VALUES (3,2,3,'#00931',1662626904,1663970400,200);
Volume is the kicker.
What i want, if I use volume amount lets say in this case its 3000 I get a return that the max volume be created is X because not all raw materials are present.
The base is 1000 = 100 so for 3000 it is 300 and only 1 raw material has the required stock. So that means it will be max 2000 volume. And if there is no volume that can be produced then 0.
results;
CREATE TABLE `results` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`volume` int(11) NOT NULL,
`quantity_needed` mediumtext NOT NULL,
`stock` mediumtext NOT NULL,
`result` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
INSERT INTO `results` (`id`,`volume`,`quantity_needed`,`stock`,`result`) VALUES (1,1000,'100,100','400,200',1000);
INSERT INTO `results` (`id`,`volume`,`quantity_needed`,`stock`,`result`) VALUES (2,400,'100,100','400,200',2000);
INSERT INTO `results` (`id`,`volume`,`quantity_needed`,`stock`,`result`) VALUES (3,3000,'100,100','400,200',2000);
INSERT INTO `results` (`id`,`volume`,`quantity_needed`,`stock`,`result`) VALUES (4,500,'100,100','400,200',500);
INSERT INTO `results` (`id`,`volume`,`quantity_needed`,`stock`,`result`) VALUES (5,500,'50,75','400,200',500);
INSERT INTO `results` (`id`,`volume`,`quantity_needed`,`stock`,`result`) VALUES (6,500,'50,75','25,75',250);
INSERT INTO `results` (`id`,`volume`,`quantity_needed`,`stock`,`result`) VALUES (7,500,'30,30','25,75',416);
Hope there is a SQL wizard that can help me out.
I think you are looking for something like
SELECT r.id,
r.volume,
group_concat(rg.aantal ORDER BY rg.id SEPARATOR ',') quantity_needed,
group_concat(g.voorraad ORDER BY rg.id SEPARATOR ',') stock,
min(floor(g.voorraad/rg.aantal)) * r.volume result
FROM recepten r INNER JOIN receptgrondstoffen rg
on r.id = rg.receptid
inner join grondstofbatch g
on g.id = rg.grondstofid
GROUP BY r.id, r.volume
You can see it with your sample data in this fiddle.
(I am possibly misunderstanding your problem since your result data doesn't seem to match your sample data).
The idea here is that, for each recepten, calculate min(floor(grondstofbatch.voorraad/receptgrondstoffen.aantal)). Floor since we want an integer (e.g. if we need 100 units for the recipe and actually have 250 units, floor(250/100) = 2 possible batches). Min since we want the limiting factor (e.g. it doesn't matter if one item in the recipe has enough for 20 batches if another item only has enough for 1 batch).
Hopefully this is in the ballpark of what you're looking for.
Edited: To handle the case where to sum the available quantities I have changed the alias g to be a subquery using the grondstofid table (rather than just the straight grondstofid table). I also realize I was likely joining the grondstofid table incorrectly above (g.id = rg.grondstofid rather than g.grondstofid = rg.grondstofid).
SELECT r.id,
r.volume,
group_concat(rg.aantal ORDER BY rg.id SEPARATOR ',') quantity_needed,
group_concat(g.voorraad ORDER BY rg.id SEPARATOR ',') stock,
min(floor(g.voorraad/rg.aantal)) * r.volume result
FROM recepten r INNER JOIN receptgrondstoffen rg
on r.id = rg.receptid
inner join (SELECT grondstofid, sum(voorraad) voorraad FROM grondstofbatch GROUP BY grondstofid) g
on g.grondstofid = rg.grondstofid
GROUP BY r.id, r.volume
Please take a look at a fiddle of this version

MYSQL Select group by order by

i have this table:
messages
/*Table structure for table `messages` */
CREATE TABLE `messages` (
`id` int(255) NOT NULL AUTO_INCREMENT,
`fromperson` varchar(255) NOT NULL,
`sent` datetime(6) NOT NULL,
`msgread` int(2) DEFAULT 0,
`content` text DEFAULT NULL,
`toperson` varchar(255) NOT NULL,
`route` int(2) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=75508 DEFAULT CHARSET=utf8mb4;
/*Data for the table `messages` */
insert into `messages`(`id`,`fromperson`,`sent`,`msgread`,`content`,`toperson`,`route`) values
(75477,'jaritje','2020-07-31 11:47:59.000000',1,'helemaal niks :)','anaisje',0),
(75478,'jaritje','2020-07-31 11:48:25.000000',1,'wdj','anaisje',1),
(75479,'jaritje','2020-05-25 12:57:27.000000',1,'cv','anaisje',0),
(75501,'jaritje','2020-05-25 13:38:31.000000',1,'gmj*','anaisje',1),
(75502,'jaritje','2020-05-25 13:38:48.000000',1,'gm','anaisje',1),
(75503,'jaritje','2020-05-26 16:53:27.000000',1,'hgh','anaisje',0),
(75504,'jaritje','2020-05-26 17:05:27.000000',1,'hey\r\n','anaisje',1),
(75505,'jaritje','2020-05-26 18:14:03.000000',1,'hallo','anaisje',0),
(75507,'jaritje','2020-07-22 12:57:27.000000',1,'TEST ','saartje',1);
Now i want to select every most recent message with every person.
So the most recent message with "anaisje" and with "saartje".
So i want the rows with id 75478 and 75507.
I read on the internet that
SELECT * FROM (SELECT * FROM messages ORDER BY sent DESC) AS person WHERE fromperson = ?
should work, but it doesn't for me...
Anyone can help me with this?
Thanks in advance,
Jari
To get the most recent row of data by sender and receiver, you can use a self join as follows:
select *
from messages msg
where sent = (select max(sent)
from messages msg_
where msg_.fromperson = msg.fromperson
and msg_.toperson = msg.toperson)
See how it works in this Fiddle

Mysql Multiple statements different conditions

I have a mysql table:
CREATE TABLE `templates_assignments` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`type` int(11) NOT NULL DEFAULT '2'
`assignment_id` int(11) NOT NULL DEFAULT '1',
`template_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `template_id` (`template_id`),
) ENGINE=InnoDB AUTO_INCREMENT=122 DEFAULT CHARSET=latin1;
/*Data for the table `templates_assignments` */
insert into `templates_assignments`
(`id`,`type`,`assignment_id`,`template_id`)
values
(15,1,1,1),
(16,1,1,2),
(19,1,1,6),
(54,2,30,6),
(55,1,5,11),
(56,1,5,15),
(57,1,5,22);
I want to select the template that qualifies for both conditions:
type=2 AND assignment_id=30
type=1 AND assignment_id=1
the only template_id that should come back is 6, but i keep getting all or none.
My query condition was something like:
WHERE
(
(templatesAssignments.type=2 AND templatesAssignments.assignment_id=30) AND (templatesAssignments.type=1 AND templatesAssignments.assignment_id=1)
)
But no luck...what am i missing?
SELECT ta1.template_id
FROM templatesAssignments ta1
INNER JOIN templatesAssignments ta2 ON ta1.template_id = ta2.template_id
WHERE (ta1.type=1 AND ta1.assignment_id=1)
AND (ta2.type=2 AND ta2.assignment_id=30)
select template_id
from templatesAssignments
group by template_id
having sum(type=2 AND assignment_id=30) > 0
and sum(type=1 AND assignment_id=1) > 0

mySql subtract row of different table

I want to subtract between two rows of different table:
I have created a view called leave_taken and table called leave_balance.
I want this result from both table:
leave_taken.COUNT(*) - leave_balance.balance
and group by leave_type_id_leave_type
Code of both table
-----------------View Leave_Taken-----------
CREATE ALGORITHM = UNDEFINED DEFINER=`1`#`localhost` SQL SECURITY DEFINER
VIEW `leave_taken`
AS
select
`leave`.`staff_leave_application_staff_id_staff` AS `staff_leave_application_staff_id_staff`,
`leave`.`leave_type_id_leave_type` AS `leave_type_id_leave_type`,
count(0) AS `COUNT(*)`
from
(
`leave`
join `staff` on((`staff`.`id_staff` = `leave`.`staff_leave_application_staff_id_staff`))
)
where (`leave`.`active` = 1)
group by `leave`.`leave_type_id_leave_type`;
----------------Table leave_balance----------
CREATE TABLE IF NOT EXISTS `leave_balance` (
`id_leave_balance` int(11) NOT NULL AUTO_INCREMENT,
`staff_id_staff` int(11) NOT NULL,
`leave_type_id_leave_type` int(11) NOT NULL,
`balance` int(3) NOT NULL,
`date_added` date NOT NULL,
PRIMARY KEY (`id_leave_balance`),
UNIQUE KEY `id_leave_balance_UNIQUE` (`id_leave_balance`),
KEY `fk_leave_balance_staff1` (`staff_id_staff`),
KEY `fk_leave_balance_leave_type1` (`leave_type_id_leave_type`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
------- Table leave ----------
CREATE TABLE IF NOT EXISTS `leave` (
`id_leave` int(11) NOT NULL AUTO_INCREMENT,
`staff_leave_application_id_staff_leave_application` int(11) NOT NULL,
`staff_leave_application_staff_id_staff` int(11) NOT NULL,
`leave_type_id_leave_type` int(11) NOT NULL,
`date` date NOT NULL,
`active` int(11) NOT NULL DEFAULT '1',
`date_updated` date NOT NULL,
PRIMARY KEY (`id_leave`,`staff_leave_application_id_staff_leave_application`,`staff_leave_application_staff_id_staff`),
KEY `fk_table1_leave_type1` (`leave_type_id_leave_type`),
KEY `fk_table1_staff_leave_application1` (`staff_leave_application_id_staff_leave_application`,`staff_leave_application_staff_id_staff`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=32 ;
Well, I still don't think you've provided enough information. It would be very helpful to have some sample data and your expected output (in tabular format). That said, I may have something you can start working with. This query finds all staff members, calculates their current leave (grouped by type), and determines the difference between that and their balance by leave type. Take a look at it, and more importantly (perhaps) the sqlfiddle here that I used which has the sample data in it (very important to determining if this is the correct path for your data).
SELECT
staff.id_staff,
staff.name,
COUNT(`leave`.id_leave) AS leave_count,
leave_balance.balance,
(COUNT(`leave`.id_leave) - leave_balance.balance) AS leave_difference,
`leave`.leave_type_id_leave_type AS leave_type
FROM
staff
JOIN `leave` ON staff.id_staff = `leave`.staff_leave_application_staff_id_staff
JOIN leave_balance ON
(
staff.id_staff = leave_balance.staff_id_staff
AND `leave`.leave_type_id_leave_type = leave_balance.leave_type_id_leave_type
)
WHERE
`leave`.active = 1
GROUP BY
staff.id_staff, leave_type;
Good luck!

Social Networking Friends table - Explain Plan - Error Failed to enable constraints error

I have a below table structure for friends table
TABLE STRUCTURE
CREATE TABLE `my_friends` (
`first_user_id` int(10) unsigned NOT NULL,
`second_user_id` int(10) unsigned NOT NULL,
`approved` tinyint(1) NOT NULL DEFAULT '0',
`request_sent` int(10) unsigned DEFAULT NULL,
`request_approved` int(10) unsigned DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
and
DATA
insert into `my_friends` values (4,1,1,null,null);
insert into `my_friends` values (7,8,1,null,null);
insert into `my_friends` values (1,7,1,null,null);
insert into `my_friends` values (2,7,1,null,null);
insert into `my_friends` values (4,2,1,null,null);
To get all the friends for user id "1" , I am running the below query
QUERY TO GET FRIENDS
SELECT first_user_id user_id, second_user_id friend_id from my_friends where first_user_id=1 and approved=1
union
SELECT second_user_id user_id ,first_user_id friend_id from my_friends where second_user_id=1 and approved=1
and when I check explain plan for this , this throws
EXPLAIN PLAN ERROR
Error
Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.
I am using this query in most of the queries as a subquery and this one causing the issue to check explain plan for all other queries
This is an issue with Mysql and raised with mysql