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
I am exposing my concern to you.
There are "demande_psy" and "consultant" tables. Each "demande_psy" record can relate to several "consultants" records, and each "consultant" record can relate to several "demande_psy" records, according to a "statut". This is the reason why, the primary key of the "demande_psy_consultant" link table (many to many relation table) is composed of: "id_demande_psy", "id_consultant", "statut". By querying the database , I need to retrieve a list of demande_psy and their priority statut, according to these 3 rules:
If among the same demand_psy, I have at least one AFFECTED status => my request line must display the "Affected" status
Otherwise, if among the same demande_psy, I have at least one status ACCEPTED => my demande_psy line must display "Accepted"
Otherwise my demande_psy line should show "Sent"
Here my tables creation code :
CREATE TABLE `demande_psy` (
`id` int(10) UNSIGNED NOT NULL,
`titre` varchar(255) NOT NULL,
`detail` text NOT NULL,
`sms` text NOT NULL,
`created_at` datetime NOT NULL,
`modified_at` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `demande_psy` (`id`, `titre`, `detail`, `sms`, `created_at`)
VALUES (1, 'Test demande', 'bla bla bla bla', 'qsdf\r\nqsdf\r\n', '2021-03-18 17:23:59');
ALTER TABLE `demande_psy` ADD PRIMARY KEY (`id`);
ALTER TABLE `demande_psy` MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=6;
CREATE TABLE `consultant` (
`id` int(11) UNSIGNED NOT NULL,
`prenom` varchar(100) DEFAULT NULL,
`nom` varchar(100) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `consultant` (`id`, `prenom`, `nom`) VALUES
(52, 'Michel', 'Moral (Somica - Undici)'),
(55, 'Patrick', 'Amar');
ALTER TABLE `consultant` ADD PRIMARY KEY (`id`);
ALTER TABLE `consultant` MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=56;
CREATE TABLE `demande_psy_consultant` (
`id_demande_psy` int(10) UNSIGNED NOT NULL,
`id_consultant` int(10) UNSIGNED NOT NULL,
`statut` enum('SENT','ACCEPTED','AFFECTED') NOT NULL,
`created_at` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `demande_psy_consultant` (`id_demande_psy`, `id_consultant`,
`statut`, `created_at`) VALUES
(1, 52, 'SENT', '2021-03-18 17:39:59'),
(1, 55, 'ACCEPTED', '2021-03-18 19:05:45');
ALTER TABLE `demande_psy_consultant` ADD PRIMARY KEY (`id_demande_psy`,`id_consultant`,`statut`);
ALTER TABLE `demande_psy_consultant`
ADD CONSTRAINT `fk_consultant` FOREIGN KEY (`id_consultant`) REFERENCES `consultant` (`id`),
ADD CONSTRAINT `fk_demande_psy` FOREIGN KEY (`id_demande_psy`) REFERENCES `demande_psy` (`id`);
Here a simplified example :
demande_psy
-----------
1 toto
6 titi
consultant
----------
15 Marc
88 Jean
demande_psy_consultant
----------------------
1 15 SENT
1 62 SENT
1 88 ACCEPTED
1 88 AFFECTED
6 88 SENT
6 15 SENT
==> EXPECTED RESULT
---------------------------------------------------
1 88 AFFECTED (according to the 3 rules)
6 15 SENT
And now, here is my sql query:
SELECT
DPC.id_demande_psy,
DPC.id_consultant,
(CASE
WHEN (SELECT count(DPC.statut) FROM demande_psy_consultant DPC WHERE DPC.statut = "AFFECTED")>0 THEN "AFFECTED"
WHEN (SELECT count(DPC.statut) FROM demande_psy_consultant DPC WHERE DPC.statut = "ACCEPTED")>0 THEN "ACCEPTED"
ELSE "SENT"
END) as statutComputed
FROM demande_psy_consultant DPC
GROUP BY DPC.id_demande_psy
With it, I obtain :
MY (BAD) RESULT
---------------
1 15 AFFECTED
6 15 AFFECTED
So I struggle a bit to correct it to obtain the desired result If anyone has an idea, I'm interested
thank you !
My environment is Server version: 5.1.72-community MySQL Community Server (GPL).
An example:
CREATE TABLE `pe` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`person_id` int(11) NOT NULL,
`height` int(3) DEFAULT NULL,
`weight` double(5,1) DEFAULT NULL,
`pe_time` date NOT NULL DEFAULT '0000-00-00',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_id` (`person_id`,`pe_time`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
And I have some rows in table pe, some of them like:
person_id, height, weight, pe_time
10051, 160, 55, '2017-10-20'
10052, 172, 60, '2018-01-09'
Now, given a new row like:
person_id, height, weight, pe_time
10052, 172, 61, '2018-01-10'
Because there is a row which pe_time's year is 2018 and the person_id = 10052, so I want to update that row, set each field as the new value.
But, given a new row like:
person_id, height, weight, pe_time
10051, 161, 57, '2018-01-10'
Because there is not a row which pe_time's year is 2018 and the person_id = 10051, so I want to insert the new row.
As this, I want the
UNIQUE KEY is `uk_id` (`person_id`,**`pe_time's year`**).
If no way to create that UNIQUE KEY, how to write the sql
INSERT INTO... ON DUPLICATE KEY UPDATE...
to do this please?
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
I got two tables:
CREATE TABLE IF NOT EXISTS `groups2rights` (
`groups2rights_group_id` int(11) NOT NULL default '0',
`groups2rights_right` int(11) NOT NULL default '0',
PRIMARY KEY (`groups2rights_group_id`,`groups2rights_right`),
KEY `groups2rights_right` (`groups2rights_right`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `groups2rights` (`groups2rights_group_id`, `groups2rights_right`) VALUES (1, 35);
CREATE TABLE IF NOT EXISTS `rights` (
`right` int(11) NOT NULL auto_increment,
`right_name` varchar(255) default NULL,
`description` text NOT NULL,
`category` int(11) NOT NULL default '0',
PRIMARY KEY (`right`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=36 ;
INSERT INTO `rights` (`right`, `right_name`, `description`, `category`) VALUES
(33, 'admin_right_group_add', '', 100),
(34, 'admin_right_group_edit', '', 0),
(35, 'admin_right_group_delete', '', 0);
ALTER TABLE `groups2rights` ADD CONSTRAINT `groups2rights_ibfk_4` FOREIGN KEY (`groups2rights_right`) REFERENCES `rights` (`right`) ON DELETE CASCADE;
Now I tried to select all available Rights and also get if the group has it assigned, but somehow I'm missing some of the rights. Query:
SELECT r.*,g2r.groups2rights_group_id
FROM rights AS r
LEFT JOIN groups2rights AS g2r ON (g2r.groups2rights_right=r.right)
WHERE g2r.groups2rights_group_id=<<ID>> OR g2r.groups2rights_group_id IS NULL
ORDER BY r.category,r.right_name ASC
Any ideas?
Edit:
Updated the Code.
Expected Result be 3 Rows with 2 of them Havin a Null field and one having a value set.
If you do
SELECT r.*,g2r.group_id
FROM rights AS r
LEFT JOIN groups2rights AS g2r ON (g2r.right=r.right)
WHERE g2r.group_id=<<#id>> OR g2r.group_id IS NULL
ORDER BY r.category,r.right_name ASC
You will not gets rows where g2r.group_id <> null and also g2r.group_id <> <<#id>>
If you want to get all rows in rights and some of the rows in groups2rights you should do:
SELECT r.*,g2r.group_id
FROM rights AS r
LEFT JOIN (SELECT * FROM groups2rights WHERE group_id=<<#id>>) AS g2r
ON (g2r.right=r.right)
ORDER BY r.category,r.right_name ASC
This should work.
So you want to return all results found in the right table? In this case you should be using a RIGHT JOIN. This will return all results from the right table regardless of it matching the left table.
http://www.w3schools.com/sql/sql_join_right.asp