Sql order by two tables - mysql

I have 2 relations: tables and tablegroups. One table can be in one tablegroup and one tablegroup contains multiple tables.
I need a select that returns the following output:
All tables from the tablegroup with the sortid 0 -> the tables again sorted by their sortid
and so on for all the tables.
Is this possible in Sql(Mysql dbms)?
Table
table_id, name, pax, createdate, lastupdate, tablegroup_id, sort_id,
'2', 'tisch 02', '6', NULL, NULL, '1', '3'
'3', 'tisch 03', '4', NULL, NULL, '1', '1'
'4', 'tisch 04', '2', NULL, NULL, '1', '2'
'5', 'tisch 05', '8', NULL, NULL, '1', '4'
'6', 'tisch 101', '4', NULL, NULL, '2', '1'
'7', 'tisch 102', '6', NULL, NULL, '2', '2'
'8', 'stube 01', '2', NULL, NULL, '3', '2'
'9', 'stube 02', '3', NULL, NULL, '3', '1'
Tablegroups
tablegroup_id, name, notiz, color, customer_id, sort_id, visible
'1', 'garten', NULL, '1', '1', '2', '1'
'2', 'lounge', NULL, '2', '1', '3', '1'
'3', 'stube', '', '7', '1', '1', '1'
Expected Output:
'stube 01'
'stube 02'
'tisch 03'
'tisch 04'
'tisch 05'
'tisch 101'
'tisch 102'

Inner join table and tablegroups on a common tablegroup_id and ORDER BY the sort_id of tablegroups and then the sort_id of table.
SELECT t.name
FROM table t
INNER JOIN tablegroups tg
ON tg.tablegroup_id = t.tablegroup_id
ORDER BY tg.sort_id,
t.sort_id;

Related

Absenteeism query showing date as employee is absent

I'm trying to generate an absenteeism query with the date employees were absent.
Table "ci_admin":
DROP TABLE IF EXISTS `ci_admin`;
CREATE TABLE `ci_admin` (
`admin_id` int(11) NOT NULL AUTO_INCREMENT,
`admin_role_id` int(11) NOT NULL,
`department_id` int(11) NOT NULL,
`firstname` varchar(255) NOT NULL,
`lastname` varchar(255) NOT NULL,
`emp_photo` varchar(255) NOT NULL,
PRIMARY KEY (`admin_id`)
);
INSERT INTO `ci_admin` VALUES ('1', '20170079320', '1', '1', 'AHMED', 'MAKOKHA', '125.jpg'), ('2', '20170079321', '1', '1', 'MARIAM', 'AHMED', '2.png'), ('3', '20170080091', '2', '3', 'SALAHUDEEN', 'AHMED', '3.png'), ('4', '20130080083', '2', '2', 'NURU', 'ABBAS', '4.png'), ('5', '20170080092', '5', '1', 'HIRBO', 'ALI', '5.png');
Table "ci_department":
DROP TABLE IF EXISTS `ci_department`;
CREATE TABLE `ci_department` (
`department_id` int(11) NOT NULL AUTO_INCREMENT,
`admin_id` int(11) NOT NULL,
`department_name` varchar(225) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`department_id`)
);
INSERT INTO `ci_department` VALUES ('1', 'INFORMATION COMMUNICATION TECHNOLOGY'), ('2', 'HUMAN RESOURCE'), ('3', 'PROCUREMENT');
Table "ci_admnin_roles":
DROP TABLE IF EXISTS `ci_admin_roles`;
CREATE TABLE `ci_admin_roles` (
`admin_role_id` int(11) NOT NULL AUTO_INCREMENT,
`admin_role_title` varchar(30) CHARACTER SET utf8 NOT NULL,
PRIMARY KEY (`admin_role_id`)
);
INSERT INTO `ci_admin_roles` VALUES ('1', 'Super Admin'), ('2', 'ADMIN'), ('3', 'ACCOUNTANT'), ('4', 'OPERATOR'), ('5', 'IT OFFICER'), ('6', 'APPLICANT');
Table "ci_attendance":
DROP TABLE IF EXISTS `ci_attendance`;
CREATE TABLE `ci_attendance` (
`attendance_id` int(11) NOT NULL AUTO_INCREMENT,
`attendance_date` date NOT NULL,
`admin_id` int(11) NOT NULL,
`check_in` time NOT NULL,
`check_out` time NOT NULL,
PRIMARY KEY (`attendance_id`)
);
INSERT INTO `ci_attendance` VALUES ('1', '2022-12-22', '1', '08:15:00', '18:30:00'), ('2', '2022-12-22', '2', '09:00:00', '18:30:00'), ('3', '2022-12-22', '3', '10:00:00', '19:30:00'), ('4', '2020-02-21', '1', '10:30:00', '20:30:00'), ('5', '2023-12-12', '2', '10:00:00', '21:30:00'), ('6', '2023-12-23', '3', '10:00:00', '22:30:00'), ('7', '2023-12-22', '3', '08:00:00', '17:30:00'), ('8', '2021-02-21', '2', '09:00:00', '18:30:00'), ('9', '2024-12-12', '3', '10:00:00', '19:30:00'), ('10', '2024-12-23', '1', '10:00:00', '20:30:00'), ('11', '2024-12-22', '2', '10:00:00', '21:30:00'), ('12', '2022-02-21', '3', '10:00:00', '22:30:00'), ('13', '2022-12-12', '1', '08:00:00', '17:30:00'), ('14', '2022-12-23', '3', '09:00:00', '18:30:00'), ('15', '2022-12-02', '2', '10:00:00', '19:30:00'), ('16', '2020-02-21', '1', '09:45:00', '22:00:00'), ('17', '2023-12-12', '2', '10:00:00', '21:30:00'), ('18', '2020-12-23', '3', '10:00:00', '22:30:00'), ('19', '2023-12-22', '1', '08:00:00', '17:30:00'), ('20', '2021-02-21', '2', '09:00:00', '18:30:00'), ('21', '2024-12-03', '2', '10:00:00', '19:30:00'), ('22', '2021-12-23', '1', '10:00:00', '20:30:00'), ('23', '2024-10-22', '3', '10:00:00', '21:30:00'), ('24', '2022-02-21', '3', '10:00:00', '22:30:00'), ('25', '2022-12-12', '1', '08:00:00', '17:30:00'), ('26', '2022-09-23', '2', '09:00:00', '18:30:00'), ('27', '2022-12-22', '4', '10:00:00', '19:30:00'), ('28', '2020-02-21', '1', '10:00:00', '20:30:00'), ('29', '2023-04-12', '5', '10:00:00', '21:30:00'), ('30', '2023-12-03', '4', '10:00:00', '22:30:00'), ('31', '2023-12-22', '1', '08:00:00', '17:30:00'), ('32', '2021-02-21', '5', '09:00:00', '18:30:00'), ('33', '2024-12-12', '4', '10:00:00', '19:30:00');
My current MySQL query which displays employees who are absent does not include the date when the employee is absent:
SELECT ci_admin.emp_no,
ci_admin.firstname,
ci_admin.lastname,
ci_admin.emp_photo,
ci_department.department_name,
ci_admin_roles.admin_role_title
FROM ci_admin
INNER JOIN ci_department ON ci_department.department_id = ci_admin.department_id
INNER JOIN ci_admin_roles on ci_admin_roles.admin_role_id=ci_admin.admin_role_id
WHERE ci_admin.is_deleted = 0
AND ci_admin.admin_id NOT IN (SELECT ci_attendance.admin_id
FROM ci_attendance
WHERE ci_attendance.attendance_date BETWEEN '2023-01-01' AND '2023-01-31')
ORDER BY ci_admin.department_id
I want the specific date that an employee is absent to be included in my query. How can I modify my query?

Replace ID according to value in another column in MySQL

id ver name order
'1', '0', 'John', '1'
'2', '0', 'Jill', '2'
'3', '0', 'Tania', '3'
'4', '0', 'susan', '5'
'5', '0', 'sam', '6'
'6', '0', 'Josh', '7'
'7', '0', 'Jane', '10'
'8', '0', 'Jade', '11'
'9', '0', 'Ane', '8'
'10', '0', 'Ant', '4'
Now I need to arrange in a way that "order" is sequentially arrange such as this
id ver name order
'1', '0', 'John', '1'
'2', '0', 'Jill', '2'
'3', '0', 'Tania', '3'
'4', '0', 'Ant', '4'
'5', '0', 'susan', '5'
'6', '0', 'sam', '6'
'7', '0', 'Josh', '7'
'8', '0', 'Ane', '8'
'9', '0', 'Jane', '9'
'10', '0', 'Jade', '10'
Any suggestions are welcome
I think this resolve your problem.
UPDATE table_name
SET id = order;

Get the the product with highest sells in each store - keep getting wrong products but right quantities

For the following table I want to get a table that shows the most sold product in each store
Same product can be the most sold in more than 1 store.
This is the query I tried:
SELECT StoreID, ProductID, MAX(Quantity), TotalPrice FROM MyTable GROUP BY StoreID LIMIT 0, 99999;
The answer I get is:
|StoreID|ProductID|MAX(Quantity)|TotalPrice
'1', '1', '566', '288.0000'
'2', '1', '782', '648.0000'
'3', '1', '473', '172.8000'
The problem:
I've checked and the max quantities are correct
but for some reason it shows the ID '1' for every product even that it's not the most sold product in any store.
For this table (Called 'MyTable'):
|StoreID|TotalPrice|ProductID|Quantity
'1', '288.0000', '1', '167'
'1', '760.0000', '2', '417'
'1', '400.0000', '3', '70'
'1', '352.0000', '4', '218'
'1', '1105.0000', '5', '117'
'1', '600.0000', '6', '156'
'1', '300.0000', '7', '193'
'1', '960.0000', '8', '84'
'1', '1552.0000', '9', '36'
'1', '558.0000', '10', '115'
'1', '201.6000', '11', '218'
'1', '152.0000', '12', '8'
'1', '9.6000', '13', '187'
'1', '167.4000', '14', '47'
'1', '62.0000', '15', '42'
'1', '417.0000', '16', '451'
'1', '936.0000', '17', '345'
'1', '450.0000', '18', '112'
'1', '7.3000', '19', '68'
'1', '1701.0000', '20', '66'
'1', '80.0000', '21', '337'
'1', '100.8000', '22', '58'
'1', '151.2000', '23', '275'
'1', '43.2000', '24', '431'
'1', '44.8000', '25', '171'
'1', '1245.0000', '26', '297'
'1', '526.5000', '27', '185'
'1', '1528.8000', '28', '127'
'1', '1485.0000', '29', '61'
'1', '124.2000', '30', '158'
'1', '600.0000', '31', '566'
'1', '153.6000', '32', '91'
'1', '120.0000', '33', '294'
'1', '112.0000', '34', '62'
'1', '57.6000', '35', '249'
'1', '456.0000', '36', '200'
'1', '208.0000', '37', '18'
'1', '4216.0000', '38', '86'
'1', '57.6000', '39', '192'
'1', '735.0000', '40', '431'
'1', '123.2000', '41', '220'
'1', '22.4000', '42', '183'
'1', '920.0000', '43', '141'
'1', '325.5000', '44', '281'
'1', '114.0000', '45', '360'
'1', '288.0000', '46', '249'
'1', '418.0000', '47', '156'
'1', '191.2500', '48', '45'
'1', '240.0000', '49', '45'
'1', '406.2500', '50', '25'
'1', '1696.0000', '51', '271'
'1', '112.0000', '52', '146'
'1', '1048.0000', '53', '202'
'1', '59.0000', '54', '180'
'1', '384.0000', '55', '147'
'1', '2128.0000', '56', '428'
'1', '234.0000', '57', '146'
'1', '318.0000', '58', '201'
'1', '3080.0000', '59', '504'
'1', '544.0000', '60', '433'
'1', '364.8000', '61', '221'
'1', '591.0000', '62', '247'
'1', '2808.0000', '63', '187'
'1', '1330.0000', '64', '194'
'1', '336.0000', '65', '250'
'1', '816.0000', '66', '110'
'1', '56.0000', '67', '105'
'1', '30.0000', '68', '245'
'1', '432.0000', '69', '305'
'1', '252.0000', '70', '254'
'1', '344.0000', '71', '326'
'1', '556.0000', '72', '400'
'1', '240.0000', '73', '143'
'1', '400.0000', '74', '70'
'1', '186.0000', '75', '490'
'1', '216.0000', '76', '348'
'1', '104.0000', '77', '255'
'2', '648.0000', '1', '317'
'2', '608.0000', '2', '453'
'2', '160.0000', '3', '128'
'2', '422.4000', '4', '109'
'2', '85.4000', '5', '124'
'2', '150.0000', '6', '77'
'2', '240.0000', '7', '332'
'2', '2240.0000', '8', '222'
'2', '4850.0000', '9', '53'
'2', '396.8000', '10', '435'
'2', '403.2000', '11', '293'
'2', '570.0000', '12', '107'
'2', '96.0000', '13', '477'
'2', '279.0000', '14', '224'
'2', '155.0000', '15', '60'
'2', '139.0000', '16', '294'
'2', '468.0000', '17', '416'
'2', '2000.0000', '18', '218'
'2', '109.5000', '19', '422'
'2', '2592.0000', '20', '219'
'2', '160.0000', '21', '286'
'2', '201.6000', '22', '204'
'2', '180.0000', '23', '187'
'2', '54.0000', '24', '363'
'2', '134.4000', '25', '120'
'2', '249.0000', '26', '164'
'2', '1755.0000', '27', '80'
'2', '1019.2000', '28', '281'
'2', '1980.0000', '29', '458'
'2', '165.6000', '30', '175'
'2', '200.0000', '31', '533'
'2', '1024.0000', '32', '176'
'2', '50.0000', '33', '233'
'2', '156.8000', '34', '158'
'2', '288.0000', '35', '348'
'2', '608.0000', '36', '359'
'2', '468.0000', '37', '18'
'2', '4216.0000', '38', '292'
'2', '604.8000', '39', '317'
'2', '588.0000', '40', '518'
'2', '77.0000', '41', '301'
'2', '112.0000', '42', '223'
'2', '552.0000', '43', '298'
'2', '248.0000', '44', '136'
'2', '380.0000', '45', '40'
'2', '48.0000', '46', '230'
'2', '121.6000', '47', '197'
'2', '153.0000', '48', '15'
'2', '640.0000', '49', '344'
'2', '195.0000', '50', '101'
'2', '1484.0000', '51', '328'
'2', '44.8000', '52', '198'
'2', '393.0000', '53', '320'
'2', '59.0000', '54', '295'
'2', '403.2000', '55', '283'
'2', '121.6000', '56', '486'
'2', '249.6000', '57', '202'
'2', '318.0000', '58', '102'
'2', '660.0000', '59', '630'
'2', '1088.0000', '60', '782'
'2', '2052.0000', '61', '177'
'2', '591.0000', '62', '399'
'2', '280.8000', '63', '223'
'2', '931.0000', '64', '397'
'2', '252.0000', '65', '229'
'2', '408.0000', '66', '95'
'2', '210.0000', '67', '55'
'2', '200.0000', '68', '298'
'2', '518.4000', '69', '232'
'2', '240.0000', '70', '299'
'2', '34.4000', '71', '258'
'2', '667.2000', '72', '200'
'2', '300.0000', '73', '85'
'2', '168.0000', '74', '92'
'2', '37.2000', '75', '542'
'2', '86.4000', '76', '367'
'2', '124.8000', '77', '236'
'3', '172.8000', '1', '344'
'3', '304.0000', '2', '187'
'3', '240.0000', '3', '130'
'3', '1100.0000', '4', '126'
'3', '204.0000', '5', '57'
'3', '120.0000', '6', '68'
'3', '360.0000', '7', '238'
'3', '400.0000', '8', '66'
'3', '582.0000', '9', '6'
'3', '595.2000', '10', '192'
'3', '168.0000', '11', '195'
'3', '364.8000', '12', '229'
'3', '48.0000', '13', '227'
'3', '167.4000', '14', '133'
'3', '248.0000', '15', '20'
'3', '486.5000', '16', '413'
'3', '249.6000', '17', '217'
'3', '600.0000', '18', '209'
'3', '131.4000', '19', '233'
'3', '1814.4000', '20', '28'
'3', '80.0000', '21', '393'
'3', '840.0000', '22', '86'
'3', '288.0000', '23', '118'
'3', '100.8000', '24', '331'
'3', '112.0000', '25', '27'
'3', '597.6000', '26', '292'
'3', '877.5000', '27', '100'
'3', '728.0000', '28', '232'
'3', '990.0000', '29', '227'
'3', '1242.0000', '30', '279'
'3', '150.0000', '31', '298'
'3', '320.0000', '32', '30'
'3', '40.0000', '33', '228'
'3', '224.0000', '34', '286'
'3', '1440.0000', '35', '286'
'3', '380.0000', '36', '246'
'3', '20.8000', '37', '89'
'3', '10540.0000', '38', '245'
'3', '86.4000', '39', '284'
'3', '882.0000', '40', '154'
'3', '192.5000', '41', '460'
'3', '98.0000', '42', '291'
'3', '1472.0000', '43', '141'
'3', '620.0000', '44', '184'
'3', '228.0000', '45', '108'
'3', '144.0000', '46', '69'
'3', '114.0000', '47', '132'
'3', '714.0000', '48', '78'
'3', '560.0000', '49', '131'
'3', '195.0000', '50', '109'
'3', '127.2000', '51', '287'
'3', '112.0000', '52', '156'
'3', '262.0000', '53', '200'
'3', '29.5000', '54', '280'
'3', '2304.0000', '55', '473'
'3', '60.8000', '56', '349'
'3', '312.0000', '57', '86'
'3', '848.0000', '58', '231'
'3', '1320.0000', '59', '362'
'3', '952.0000', '60', '362'
'3', '712.5000', '61', '205'
'3', '472.8000', '62', '437'
'3', '175.5000', '63', '35'
'3', '239.4000', '64', '149'
'3', '672.0000', '65', '266'
'3', '136.0000', '66', '34'
'3', '336.0000', '67', '24'
'3', '100.0000', '68', '256'
'3', '28.8000', '69', '177'
'3', '60.0000', '70', '264'
'3', '516.0000', '71', '473'
'3', '174.0000', '72', '206'
'3', '525.0000', '73', '65'
'3', '288.0000', '74', '135'
'3', '37.2000', '75', '123'
'3', '475.2000', '76', '266'
'3', '156.0000', '77', '300'
Try something like below:
SELECT *
FROM MyTable WHERE (storeID,Quantity) IN
( SELECT storeID, MAX(Quantity)
FROM MyTable
GROUP BY storeID
)
The query you wrote is ambiguous. ProductID is not the product that had the max quantity. Think about this query:
SELECT StoreID, ProductID, MAX(Quantity), MIN(Quantity), TotalPrice
FROM MyTable
GROUP BY StoreID LIMIT 0, 99999;
Which ProductID do you expect this query to return? The product that has the max quantity or the product that has the min quantity?
Or this:
SELECT StoreID, ProductID, AVG(Quantity), TotalPrice
FROM MyTable
GROUP BY StoreID LIMIT 0, 99999;
Perhaps no product has a quantity that is exactly the average quantity.
This type of SQL query is technically illegal and it's an error in most databases other than MySQL. MySQL allows it, and trusts you to know when you're writing such an ambiguous query.
Tip: Every column of your select-list must be either:
Inside an aggregate function
Named in the GROUP BY clause.
Any other column will not return a reliable value.
You're asking for a query that has been dubbed the greatest-n-per-group problem. This question comes up frequently on Stack Overflow, and it has been answered many times. Here's a couple of my past answers that got a lot of upvotes:
Retrieving the last record in each group
Fetch the row which has the Max value for a column
It matches because you're grouping by StoreID. MAX is a GROUP BY function, so it returns the MAX(Quantity) for each StoreID.
For ProductID and TotalPrice, the query is just returning the values from the first row for each store, because there's nothing telling it to read the values from the row where Quantity=MAX(Quantity)
TheUknown's query, on the other hand, first finds the MAX(Quantity) for each store, then does a second query to return all the fields from the row where Quantity=MAX(Quantity)

MySql grouping returns incorrect result

Okay i am attempting to do some SQL magic but sadly it doesnt work as expected. i have the following query:
select
`U`.`id` AS `user_id`,
`athm`.`academy_module_id` AS `module_id`,
`AHAT`.`academy_team_id` AS `team_id`,
(case
when
((`act`.`module_id` = `athm`.`academy_module_id`)
and (`act`.`team_id` = `athm`.`academy_team_id`))
then
1
else 0
end) AS `is_complete`
from
(((`user` `U`
join `user_has_academy_team` `AHAT` ON ((`AHAT`.`user_id` = `U`.`id`)))
join `academy_team_has_academy_module` `athm` ON ((`AHAT`.`academy_team_id` = `athm`.`academy_team_id`)))
left outer join `academy_attempt` `act` ON ((`act`.`module_id` = `athm`.`academy_module_id`)))
Now without any grouping this returns the following result:
user_id, module_id, team_id, is_complete
'1', '11', '30', '1'
'1', '11', '30', '1'
'1', '11', '30', '1'
'1', '11', '30', '1'
'1', '11', '30', '1'
'1', '11', '30', '1'
'1', '11', '30', '1'
'1', '11', '30', '1'
'1', '11', '30', '1'
'1', '12', '30', '1'
'1', '12', '30', '1'
'1', '12', '30', '1'
'1', '12', '30', '1'
'1', '5', '32', '0'
'1', '10', '32', '0'
'1', '12', '32', '0'
'1', '12', '32', '0'
'1', '12', '32', '0'
'1', '12', '32', '0'
'3', '5', '32', '0'
'3', '10', '32', '0'
'3', '12', '32', '0'
'3', '12', '32', '0'
'3', '12', '32', '0'
'3', '12', '32', '0'
'4', '5', '32', '0'
'4', '10', '32', '0'
'4', '12', '32', '0'
'4', '12', '32', '0'
'4', '12', '32', '0'
'4', '12', '32', '0'
Let me explain my goal here:
When a so called module has been taking by my users in my application an attempt will be added into my academy_attempt. however a user may take a module several times i.e adding more rows to the academy_attempt table. (as you can see user 1 has taken some of the modules several times).
My Goal is to find out which modules has been taking and which modules has not been taking.
Sadly when i group on academy_module_id i get the following result:
user_id, module_id, team_id, is_complete
'1', '5', '32', '0'
'1', '10', '32', '0'
'1', '11', '30', '1'
'1', '12', '30', '1'
I am guessing it is because of the LEFT OUTER JOIN since the other users does not have a record inacademy_attempt the result will not be shown.
My question is, is there a work around when working with NULL data?
Here are my table stuctures:
Table: user_has_academy_team
Columns:
user_id int(11) PK
academy_team_id int(11) PK
Table: academy_team_has_academy_module
Columns:
academy_team_id int(11) PK
academy_id int(11) PK
academy_module_id int(11) PK
Table: academy_attempt
Columns:
id int(11) AI PK
user_id int(11)
academy_id int(11)
module_id int(11)
module_type_id int(11)
team_id int(11)
score int(11)
medal_id int(11) PK
timestamp datetime
possible_correct int(11)
user_correct int(11)
Table: user
Columns:
id int(11) AI PK
username varchar(100)
password varchar(100)
is_active int(11)
user_type_id int(11)
token varchar(445)
organization_id int(11)
title_id int(11)
image_path varchar(100)
division_id int(11)
Please let me know if you need more information

Optimizing query mysql

I have 3 tables in which i store some values. Everything is working fine except my query is taking too long to execute. I have around 500.000 rows in table "tickets" at the moment. I would like to know what would be the best way to optimize this query to execute SELECT faster.
One more thing: I would like to know is there a way to update all rows through query (not using my C# app). In this case i need to update column "wonamount" which is in tickets with value that i get by multiplying row "coefficient" with row "uplata" and update column status with value "2".
Here are my tables and sql:
CREATE TABLE IF NOT EXISTS `coefficients` (`number` int(11) DEFAULT NULL,`coefficient` int(11) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `coefficients` (`number`, `coefficient`) VALUES
(1, 0),
(2, 0),
(3, 0),
(4, 0),
(5, 0),
(6, 10000),
(7, 7500),
(8, 5000),
(9, 2500),
(10, 1000),
(11, 500),
(12, 300),
(13, 200),
(14, 120),
(15, 80),
(16, 70),
(17, 60),
(18, 50),
(19, 40),
(20, 35),
(21, 30),
(22, 25),
(23, 20),
(24, 15),
(25, 12),
(26, 10),
(27, 9),
(28, 8),
(29, 7),
(30, 6),
(31, 5),
(32, 4),
(33, 3),
(34, 2),
(35, 1);
CREATE TABLE IF NOT EXISTS `draws` (
`iddraws` int(11) NOT NULL AUTO_INCREMENT,
`1` varchar(255) DEFAULT NULL,
`2` varchar(45) DEFAULT NULL,
`3` varchar(45) DEFAULT NULL,
`4` varchar(45) DEFAULT NULL,
`5` varchar(45) DEFAULT NULL,
`6` varchar(45) DEFAULT NULL,
`7` varchar(45) DEFAULT NULL,
`8` varchar(45) DEFAULT NULL,
`9` varchar(45) DEFAULT NULL,
`10` varchar(45) DEFAULT NULL,
`11` varchar(45) DEFAULT NULL,
`12` varchar(45) DEFAULT NULL,
`13` varchar(45) DEFAULT NULL,
`14` varchar(45) DEFAULT NULL,
`15` varchar(45) DEFAULT NULL,
`16` varchar(45) DEFAULT NULL,
`17` varchar(45) DEFAULT NULL,
`18` varchar(45) DEFAULT NULL,
`19` varchar(45) DEFAULT NULL,
`20` varchar(45) DEFAULT NULL,
`21` varchar(45) DEFAULT NULL,
`22` varchar(45) DEFAULT NULL,
`23` varchar(45) DEFAULT NULL,
`24` varchar(45) DEFAULT NULL,
`25` varchar(45) DEFAULT NULL,
`26` varchar(45) DEFAULT NULL,
`27` varchar(45) DEFAULT NULL,
`28` varchar(45) DEFAULT NULL,
`29` varchar(45) DEFAULT NULL,
`30` varchar(45) DEFAULT NULL,
`31` varchar(45) DEFAULT NULL,
`32` varchar(45) DEFAULT NULL,
`33` varchar(45) DEFAULT NULL,
`34` varchar(45) DEFAULT NULL,
`35` varchar(45) DEFAULT NULL,
`datetime` varchar(255) DEFAULT NULL,
PRIMARY KEY (`iddraws`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=162 ;
INSERT INTO `draws` (`iddraws`, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `10`, `11`, `12`, `13`, `14`, `15`, `16`, `17`, `18`, `19`, `20`, `21`, `22`, `23`, `24`, `25`, `26`, `27`, `28`, `29`, `30`, `31`, `32`, `33`, `34`, `35`, `datetime`) VALUES
(1, '17', '46', '27', '30', '8', '11', '4', '40', '37', '36', '22', '14', '35', '47', '24', '20', '23', '10', '2', '42', '41', '43', '9', '19', '7', '48', '3', '38', '29', '44', '16', '12', '26', '13', '5', '1391130262'),
(2, '45', '2', '1', '24', '30', '4', '10', '11', '22', '3', '38', '33', '35', '14', '48', '28', '42', '27', '43', '9', '15', '29', '36', '41', '26', '23', '13', '5', '16', '20', '12', '6', '32', '37', '19', '1391134904'),
(3, '12', '46', '32', '15', '14', '41', '45', '6', '9', '20', '26', '2', '47', '37', '33', '39', '34', '17', '16', '23', '35', '29', '44', '36', '18', '40', '22', '4', '27', '30', '38', '21', '3', '43', '24', '1391135221');
CREATE TABLE IF NOT EXISTS `tickets` (
`id_tiketa` int(11) NOT NULL AUTO_INCREMENT,
`idtickets` varchar(45) DEFAULT NULL,
`b1` varchar(45) DEFAULT NULL,
`b2` varchar(45) DEFAULT NULL,
`b3` varchar(45) DEFAULT NULL,
`b4` varchar(45) DEFAULT NULL,
`b5` varchar(45) DEFAULT NULL,
`b6` varchar(45) DEFAULT NULL,
`shop` varchar(45) DEFAULT NULL,
`user` varchar(45) DEFAULT NULL,
`time` varchar(255) DEFAULT NULL,
`status` varchar(45) DEFAULT NULL,
`uplata` varchar(45) DEFAULT NULL,
`draw` varchar(45) DEFAULT NULL,
`qt` varchar(45) DEFAULT NULL,
`wonamount` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id_tiketa`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=138 ;
INSERT INTO `tickets` (`id_tiketa`, `idtickets`, `b1`, `b2`, `b3`, `b4`, `b5`, `b6`, `shop`, `user`, `time`, `status`, `uplata`, `draw`, `qt`, `wonamount`) VALUES
(75, '4-1-170-1367', '41', '47', '17', '24', '15', '44', '170', 'w1', '1391149398', '1', '1', '1', '', ''),
(76, '4-1-170-20104', '23', '27', '13', '7', '14', '42', '170', 'w1', '1391149398', '1', '1', '1', '', ''),
(91, '4-2-170-13887', '16', '4', '13', '35', '30', '9', '170', 'w1', '1391149462', '1', '1', '2', '', ''),
(92, '4-2-170-9701', '2', '32', '7', '15', '5', '34', '170', 'w1', '1391149463', '1', '1', '2', '', ''),
(93, '4-2-170-45661', '23', '24', '22', '27', '48', '6', '170', 'w1', '1391149463', '1', '1', '2', '', ''),
(98, '4-2-170-45503', '36', '13', '33', '10', '29', '9', '170', 'w1', '1391149463', '1', '1', '2', '', ''),
(99, '4-2-170-24095', '19', '35', '11', '36', '46', '40', '170', 'w1', '1391149463', '1', '1', '2', '', ''),
(100, '4-2-170-42832', '27', '32', '17', '29', '7', '21', '170', 'w1', '1391149463', '1', '1', '2', '', ''),
(101, '4-2-170-13570', '22', '23', '32', '6', '1', '28', '170', 'w1', '1391149463', '1', '1', '2', '', ''),
(103, '4-2-170-28122', '15', '10', '11', '9', '14', '48', '170', 'w1', '1391149463', '1', '1', '2', '', ''),
(116, '4-2-170-13095', '28', '20', '33', '42', '26', '14', '170', 'w1', '1391149464', '1', '1', '2', '', ''),
(118, '4-2-170-27646', '23', '14', '37', '27', '24', '19', '170', 'w1', '1391149464', '1', '1', '2', '', ''),
(124, '4-2-170-23302', '20', '23', '15', '38', '4', '45', '170', 'w1', '1391149465', '1', '1', '2', '', '');
SELECT t.idtickets,
t.uplata,
c.coefficient
FROM tickets t
INNER JOIN draws d ON(FIELD(t.b1,d.1,d.2,d.3,d.4,d.5,d.6,d.7,d.8,d.9,d.10,d.11,d.12,d.13,d.14,d.15,d.16,d.17,d.18,d.19,d.20,d.21,d.22,d.23,d.24,d.25,d.26,d.27,d.28,d.29,d.30,d.31,d.32,d.33,d.34,d.35)>0)
AND (FIELD(t.b2,d.1,d.2,d.3,d.4,d.5,d.6,d.7,d.8,d.9,d.10,d.11,d.12,d.13,d.14,d.15,d.16,d.17,d.18,d.19,d.20,d.21,d.22,d.23,d.24,d.25,d.26,d.27,d.28,d.29,d.30,d.31,d.32,d.33,d.34,d.35)>0)
AND (FIELD(t.b3,d.1,d.2,d.3,d.4,d.5,d.6,d.7,d.8,d.9,d.10,d.11,d.12,d.13,d.14,d.15,d.16,d.17,d.18,d.19,d.20,d.21,d.22,d.23,d.24,d.25,d.26,d.27,d.28,d.29,d.30,d.31,d.32,d.33,d.34,d.35)>0)
AND (FIELD(t.b4,d.1,d.2,d.3,d.4,d.5,d.6,d.7,d.8,d.9,d.10,d.11,d.12,d.13,d.14,d.15,d.16,d.17,d.18,d.19,d.20,d.21,d.22,d.23,d.24,d.25,d.26,d.27,d.28,d.29,d.30,d.31,d.32,d.33,d.34,d.35)>0)
AND (FIELD(t.b5,d.1,d.2,d.3,d.4,d.5,d.6,d.7,d.8,d.9,d.10,d.11,d.12,d.13,d.14,d.15,d.16,d.17,d.18,d.19,d.20,d.21,d.22,d.23,d.24,d.25,d.26,d.27,d.28,d.29,d.30,d.31,d.32,d.33,d.34,d.35)>0)
AND (FIELD(t.b6,d.1,d.2,d.3,d.4,d.5,d.6,d.7,d.8,d.9,d.10,d.11,d.12,d.13,d.14,d.15,d.16,d.17,d.18,d.19,d.20,d.21,d.22,d.23,d.24,d.25,d.26,d.27,d.28,d.29,d.30,d.31,d.32,d.33,d.34,d.35)>0)
INNER JOIN coefficients c ON c.number = GREATEST(FIELD(t.b1,d.1,d.2,d.3,d.4,d.5,d.6,d.7,d.8,d.9,d.10,d.11,d.12,d.13,d.14,d.15,d.16,d.17,d.18,d.19,d.20,d.21,d.22,d.23,d.24,d.25,d.26,d.27,d.28,d.29,d.30,d.31,d.32,d.33,d.34,d.35), FIELD(t.b2,d.1,d.2,d.3,d.4,d.5,d.6,d.7,d.8,d.9,d.10,d.11,d.12,d.13,d.14,d.15,d.16,d.17,d.18,d.19,d.20,d.21,d.22,d.23,d.24,d.25,d.26,d.27,d.28,d.29,d.30,d.31,d.32,d.33,d.34,d.35), FIELD(t.b3,d.1,d.2,d.3,d.4,d.5,d.6,d.7,d.8,d.9,d.10,d.11,d.12,d.13,d.14,d.15,d.16,d.17,d.18,d.19,d.20,d.21,d.22,d.23,d.24,d.25,d.26,d.27,d.28,d.29,d.30,d.31,d.32,d.33,d.34,d.35), FIELD(t.b4,d.1,d.2,d.3,d.4,d.5,d.6,d.7,d.8,d.9,d.10,d.11,d.12,d.13,d.14,d.15,d.16,d.17,d.18,d.19,d.20,d.21,d.22,d.23,d.24,d.25,d.26,d.27,d.28,d.29,d.30,d.31,d.32,d.33,d.34,d.35), FIELD(t.b5,d.1,d.2,d.3,d.4,d.5,d.6,d.7,d.8,d.9,d.10,d.11,d.12,d.13,d.14,d.15,d.16,d.17,d.18,d.19,d.20,d.21,d.22,d.23,d.24,d.25,d.26,d.27,d.28,d.29,d.30,d.31,d.32,d.33,d.34,d.35), FIELD(t.b6,d.1,d.2,d.3,d.4,d.5,d.6,d.7,d.8,d.9,d.10,d.11,d.12,d.13,d.14,d.15,d.16,d.17,d.18,d.19,d.20,d.21,d.22,d.23,d.24,d.25,d.26,d.27,d.28,d.29,d.30,d.31,d.32,d.33,d.34,d.35))
WHERE t.draw='1'
AND t.status = '1'
AND d.iddraws='1'
And yes, i need to do that for each t.draw and d.iddraws which will be same values.
While my answer is fairly general, I am assuming you are using MySQL.
Short Answer:
Do the following things one by one in the order mentioned while measuring performance improvement with each step.
Add Indexes on tickets.draw and tickets.status. Also add an index (primary key will be even better) on coefficients.number.
Use int instead of varchar wherever possible.
Convert query to stored procedure to save values of FIELD calls and reuse these values in GREATEST instead of calling FIELD again with same values.
Move calls to FIELD at INSERT/UPDATE time instead of SELECT.
Yes, you can update all rows through query. Use your SELECT query and make the following changes to it:
Replace SELECT t.idtickets,t.uplata, c.coefficient FROM by UPDATE
Add SET t.wonamount = c.coefficient*t.uplata, t.status='2' before WHERE ...
(Really) Long Answer:
Your question is a very good case for discussing SQL optimization as there are many optimization techniques that can be applied here. Let me discuss them in increasing order of complexity, so that you can implement them one by one till you are happy with the results. I will also generalize every point for community's benefit while giving precise suggestions to you. Let's start:
All SQL optimization starts with EXPLAIN. It's a sort of black magic that tells what's wrong with your query. Simply add the EXPLAIN keyword before the SELECT keyword in your query and you get a wealth of information on how your query is executed behind the scene. Here is the EXPLAIN output of your query (some fields removed for sake of brevity):
+-------+-------+---------------+---------+-------+------+-----------------+
| table | type | possible_keys | key | ref | rows | Extra |
+-------+-------+---------------+---------+-------+------+-----------------+
| d | const | PRIMARY | PRIMARY | const | 1 | |
| t | ALL | NULL | NULL | NULL | 13 | Using where |
| c | ALL | NULL | NULL | NULL | 35 | Using where;... |
+-------+-------+---------------+---------+-------+------+-----------------+
Each row covers a table involved in your query. Two important fields to look at here are key and rows. rows tells the number of rows of that table scanned for the query. The more this number, the more data MySQL has to scan, and therefore the slower your query. key tells if MySQL is using any shortcut to reduce rows. In the absence of any key, MySQL has to scan all rows of that table. So, we need to supply keys (also called indexes) to MySQL so that it can reduce rows and execute queries fast.
Here, table t (i.e. tickets) is not using any key and therefore scanning all rows (there are 13 rows in the sample data you provided in your fiddle, and 500,000 of them in the real data). So, we add keys (or indexes) to those fields of tickets table that are involved in decision making in this query. These fields are draw and status (... WHERE t.draw='1' AND t.status = '1'...).
mysql> ALTER TABLE tickets ADD INDEX idx_draw(draw);
mysql> ALTER TABLE tickets ADD INDEX idx_status(status);
Similarly, coefficients will benefit by index on number. A PRIMARY KEY on number will be even better if numbers are unique.
Integer data types (short, int, long, etc.) are significantly faster than character data types (char, varchar, etc.). So, avoid using character data types for integer data. In your data, all fields in draws table, and almost all fields in tickets table contain numeric data. (Booleans can be stored as byte instead of varchar. Also consider storing timestamps as int or long instead of varchar.)
FIELD is a costly call, especially if given a lot of arguments, as has to do a lot of work. In your query there are six distinct FIELD calls, and each is repeated in the call to GREATEST function, making 12 calls in total. Consider using stored procedures which allow you to save results of function calls in variables and reuse them later.
Performing validations during INSERT/UPDATE is better than performing them during SELECT. Consider validating your tickets.b1-b6 against draws.1-35 while inserting/updating instead of querying and your SELECT query will be much simpler and faster. The result of GREATEST can also be calculated at insert/update time and saved in an extra field in the tickets table to avoid recalculation every time during SELECT.
As with all queries, your query may need more optimizations when your data grows 100-1000 times its current size, but these should be enough for now.
does your db have indexes?
MYSQL indexes