Calculate Sum that cross 3 tables in MYSQL - mysql

I have 3 tables (trx_batch, trx_doc_trx_item).
I want user to enter id(trx_batch). Then the system will auto calculate the sum of trx_item which linked to trx_doc, and trx_doc is linked to trx_batch.
My table:
CREATE TABLE IF NOT EXISTS `trx_batch` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`batchDate` date NOT NULL,
`status` varchar(1) NOT NULL
PRIMARY KEY (`id`)
);
CREATE TABLE IF NOT EXISTS `trx_doc` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`idBatch` int(11) NOT NULL,
`subject` varchar(200) DEFAULT NULL,
`status` varchar(1) NOT NULL DEFAULT 'A',
PRIMARY KEY (`id`)
);
CREATE TABLE IF NOT EXISTS `trx_item` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`idDoc` int(11) NOT NULL,
`amount` decimal(14,4) NOT NULL,
`amtTax` decimal(12,4) DEFAULT NULL,
PRIMARY KEY (`id`)
);
Sample data that I have:
trx_batch
id: 1
trx_doc
id:1
idBatch: 1
trx_item:
id:1
idDoc:1
amount: 500
amtTax : 30
id:2
idDoc:1
amount:100
amtTax:20
If user enter 1 as id for trx_batch. The total should be 650.00.
How to write in mysql format? Please help me thanks!

SELECT
SUM( COALESCE( i.amount, 0 ) + COALESCE( i.amtTax, 0 ) ) AS SumAmountAndTax
FROM
trx_item AS i
INNER JOIN trx_doc AS d ON i.idDoc = doc.id
INNER JOIN trx_batch AS b ON d.idBatch = b.id
WHERE
b.id = :batchIdParameterValue

Related

Merge the rows and give me the total count

I want to count how many unique games a user have been played. Here's how the current SQL query looks like:
SELECT COUNT(DISTINCT d.id_game) AS c
FROM discord AS d
JOIN discord_games AS dg
ON d.id_game = dg.id
WHERE d.id_user = '1'
AND d.id_game != '0'
GROUP BY d.id_game
ORDER BY dg.data_name ASC
And here's now the database looks like:
CREATE TABLE IF NOT EXISTS `discord` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_user` int(11) NOT NULL,
`id_channel` varchar(50) NOT NULL,
`id_game` int(11) NOT NULL,
`data_muted_server` tinyint(4) NOT NULL,
`data_muted_self` tinyint(4) NOT NULL,
`data_deafen_server` tinyint(4) NOT NULL,
`data_deafen_self` tinyint(4) NOT NULL,
`data_suppressed` tinyint(4) NOT NULL,
`data_status` varchar(10) NOT NULL,
`datetime_logged` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
)
CREATE TABLE IF NOT EXISTS `discord_games` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`data_name` varchar(50) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
)
CREATE TABLE IF NOT EXISTS `discord_users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`data_id` text NOT NULL,
`data_name` varchar(50) NOT NULL,
`data_avatar` text,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
)
The SQL query counts correctly but it only counts 1 per row.
Example of how I'm thinking. If the user with the ID 1 have played the same game 24 times (for an example Battlefield 3) it will return 1 played game. If the same user plays another game 37 times, it will return 2 played games and so on.
SUM(DISTINCT ... doesn't work since it only replace 1 with the game ID.
How can I sum the rows so it displays the number 2 instead of 2 rows?
You could just remove the group by property and count the distinct games played. It will return the number of distinct gamesp layed by the user 1
SELECT COUNT(DISTINCT d.id_game) AS c
FROM discord AS d
JOIN discord_games AS dg
ON d.id_game = dg.id
WHERE d.id_user = '1'
AND d.id_game != '0'
ORDER BY dg.data_name ASC

MySQL gather data JOIN

I currently have these two tables
CREATE TABLE IF NOT EXISTS `players` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`group_id` int(11) NOT NULL DEFAULT '1',
`account_id` int(11) NOT NULL DEFAULT '0',
`level` int(11) NOT NULL DEFAULT '1',
`vocation` int(11) NOT NULL DEFAULT '0',
...
) ENGINE=InnoDB;
And
CREATE TABLE IF NOT EXISTS `player_storage` (
`player_id` int(11) NOT NULL DEFAULT '0',
`key` int(10) unsigned NOT NULL DEFAULT '0',
`value` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`player_id`,`key`),
FOREIGN KEY (`player_id`) REFERENCES `players`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB;
I want to execute the following query
SELECT
a.value,
b.name,
b.level,
b.vocation
FROM
player_storage a,
players b
LEFT JOIN players_online c AS t
ON c.player_id = b.id
WHERE
a.player_id = b.id
AND a.key = 6723
ORDER BY a.value DESC LIMIT 20
Thing is I also want to see if the record exists on the table players_online
CREATE TABLE IF NOT EXISTS `players_online` (
`player_id` int(11) NOT NULL,
PRIMARY KEY (`player_id`)
) ENGINE=MEMORY;
However my query seems to work but its not getting if the player_id exists on players_online
I only get the fields value, name, level, vocation but not a single field related to players_online
You should add a field related to your "online" table.
For example:
SELECT ...,
IF(c.player_id IS NULL, 'offline', 'online') online
FROM ...
And sure, you must to fix issue with double alias in players_online c As t
SQLFiddle

how can i extract total forum_question and fourm_answer count as subject wise in mysql i have below mysql structure

forum_question :
CREATE TABLE IF NOT EXISTS `forum_question` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
`question` text NOT NULL,
`subject_id` int(11) NOT NULL,
`student_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `subject_id` (`subject_id`,`student_id`),
KEY `student_id` (`student_id`)
)
forum_answer table
CREATE TABLE IF NOT EXISTS `forum_answer` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`answer` text NOT NULL,
`question_id` int(11) NOT NULL,
`faculty_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `question_id` (`question_id`,`faculty_id`),
KEY `faculty_id` (`faculty_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
and subject table
CREATE TABLE IF NOT EXISTS `subject` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(150) NOT NULL
)
Try this edited query, I am sure this will work
SELECT
COUNT(que.id) AS totalQuestions,
(SELECT COUNT(DISTINCT(forum_answer.id))
FROM
forum_answer
WHERE
forum_answer.question_id = que.id
GROUP BY que.id)
AS totalAns
FROM
forum_question que
INNER JOIN
subject sub
ON (que.subject_id = sub.id)
WHERE
que.id > 0
GROUP BY sub.id
If by total you mean the total amount of rows, you can do the following:
`SELECT COUNT(*) FROM forum_question WHERE subject_id=YOURSUBJECT`
if you want just all rows, remove the WHERE clause.
Please you can try this Query
SELECT
subject.name AS subject_name,
count(forum_question.id) AS total_question,
(SELECT count(forum_answer.id)
FROM
forum_answer
WHERE
forum_answer.question_id = forum_question.id) AS total_answer
FROM
subject
Inner Join forum_question ON subject.id = forum_question.subject_id
GROUP BY subject.id
Sorry it was my mistake. now I edited the query and hope it will work for you

i get wrong results from mysql join query

I have 2 tables, that i want to join, one is rooms and another is reservations.
Basically I want to search for rooms which are not reserved (not in reservation table) and to get the details of those rooms (which are not in reservation table) from room table.
Here are my tables structure:
CREATE TABLE `room` (
`roomID` int(11) NOT NULL AUTO_INCREMENT,
`hotelID` int(11) NOT NULL,
`roomtypeID` int(11) NOT NULL,
`roomNumber` int(11) NOT NULL,
`roomName` varchar(255) NOT NULL,
`roomName_en` varchar(255) NOT NULL,
`roomDescription` text,
`roomDescription_en` text,
`roomSorder` int(11) NOT NULL,
`roomVisible` tinyint(4) NOT NULL,
PRIMARY KEY (`roomID`)
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8;
CREATE TABLE `reservation` (
`reservationID` int(11) NOT NULL AUTO_INCREMENT,
`customerID` int(11) NOT NULL,
`hotelID` int(11) NOT NULL,
`reservationCreatedOn` datetime NOT NULL,
`reservationCreatedFromIp` varchar(255) CHARACTER SET greek NOT NULL,
`reservationNumberOfAdults` tinyint(4) NOT NULL,
`reservationNumberOfChildrens` tinyint(4) NOT NULL,
`reservationArrivalDate` date NOT NULL,
`reservationDepartureDate` date NOT NULL,
`reservationCustomerComment` text CHARACTER SET greek,
PRIMARY KEY (`reservationID`)
) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8;
CREATE TABLE `reservationroom` (
`reservationroomID` int(11) NOT NULL AUTO_INCREMENT,
`reservationID` int(11) NOT NULL,
`hotelID` int(11) NOT NULL,
`roomID` int(11) NOT NULL,
PRIMARY KEY (`reservationroomID`)
) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8;
Here is the query that I have right now, which gives me wrong results:
SELECT * FROM room r
LEFT JOIN reservation re
ON r.hotelID = re.hotelID
WHERE re.hotelID = 13
AND NOT
(re.reservationArrivalDate >= '2014-07-07' AND re.reservationDepartureDate <= '2014-07-13')
I also have created a fiddle, with the data from both tables included:
http://sqlfiddle.com/#!2/4bb9ea/1
Any help will be deeply appreciated
Regards, John
i agree that room number was missed,
but query template should looks like
SELECT
*
FROM
room r
LEFT JOIN reservation re
ON r.hotelID = re.hotelID
WHERE r.hotelID = 2
AND NOT (
re.hotelID IS NOT NULL
AND re.reservationArrivalDate >= '2014-07-07'
AND re.reservationDepartureDate <= '2014-09-23'
) ;
You need change table in where statement from reservation to room. Also you need add re.hotelID to where statement as well, because on where statement you need check that record is not null ans only after try to check dates
Given the newly-added reservationroom table, consider using a NOT EXISTS sub-query to find rooms without reservations:
SELECT
*
FROM
room r
WHERE NOT EXISTS
(SELECT
*
FROM
reservationroom rr
WHERE
rr.reservationroomID = r.roomID
)

my join returns 0 results

I have to following 3 tables: room, reservation and reservationroom
Their structure is as follows:
CREATE TABLE `room` (
`roomID` int(11) NOT NULL AUTO_INCREMENT,
`hotelID` int(11) NOT NULL,
`roomtypeID` int(11) NOT NULL,
`roomNumber` int(11) NOT NULL,
`roomName` varchar(255) NOT NULL,
`roomName_en` varchar(255) NOT NULL,
`roomDescription` text,
`roomDescription_en` text,
`roomSorder` int(11) NOT NULL,
`roomVisible` tinyint(4) NOT NULL,
PRIMARY KEY (`roomID`)
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8;
CREATE TABLE `reservation` (
`reservationID` int(11) NOT NULL AUTO_INCREMENT,
`customerID` int(11) NOT NULL,
`hotelID` int(11) NOT NULL,
`reservationCreatedOn` datetime NOT NULL,
`reservationCreatedFromIp` varchar(255) CHARACTER SET greek NOT NULL,
`reservationNumberOfAdults` tinyint(4) NOT NULL,
`reservationNumberOfChildrens` tinyint(4) NOT NULL,
`reservationArrivalDate` date NOT NULL,
`reservationDepartureDate` date NOT NULL,
`reservationCustomerComment` text CHARACTER SET greek,
PRIMARY KEY (`reservationID`)
) ENGINE=InnoDB AUTO_INCREMENT=46 DEFAULT CHARSET=utf8;
CREATE TABLE `reservationroom` (
`reservationroomID` int(11) NOT NULL AUTO_INCREMENT,
`reservationID` int(11) NOT NULL,
`hotelID` int(11) NOT NULL,
`roomID` int(11) NOT NULL,
PRIMARY KEY (`reservationroomID`)
) ENGINE=InnoDB AUTO_INCREMENT=46 DEFAULT CHARSET=utf8;
(please note that foreign keys have been removed from create statements for sake of simplicity)
What I am trying to do: I want to get all rooms that are not reserved for specific dates, that is only the free rooms from the specific hotel (I have its ID)
Here is the query that I have right now:
SELECT r.* FROM room r
LEFT JOIN `reservationroom` rr
ON r.`hotelID` = rr.`hotelID`
AND r.`roomID` = rr.`roomID`
LEFT JOIN `reservation` re
ON rr.`reservationID` = re.`reservationID`
WHERE (rr.`reservationroomID` = ''
OR rr.`reservationroomID` IS NULL
AND re.`reservationArrivalDate` >= 2014-08-27
AND re.`reservationDepartureDate` <= 2014-08-29
AND r.`hotelID` = 10
AND r.`roomVisible` = 1);
This query now returns 0 results. It should return 9 records, since the hotel with ID = 10 has 9 rooms that are free (no resevations for specific dates exist in the reservation table)
Can anyone give me a hand with this please? I am trying to sort this out couple of hours, without any success.
You are using left join, so conditions on all but the first table should be in the on clauses. I think you want a query more like this:
SELECT r.*
FROM room r LEFT JOIN
`reservationroom` rr
ON r.`hotelID` = rr.`hotelID` AND
r.`roomID` = rr.`roomID` LEFT JOIN
`reservation` re
ON rr.`reservationID` = re.`reservationID` AND
re.`reservationArrivalDate` >= 2014-08-27 AND
re.`reservationDepartureDate` <= 2014-08-29
WHERE r.`hotelID` = 10 AND r.`roomVisible` = 1 AND re.reservationID is null;
I'm not sure what the comparison is to the empty string. It doesn't seem necessary for this purpose.